//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension MemoryDB {
    // MARK: Enums

    public enum AZStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case multiAZ = "multiaz"
        case singleAZ = "singleaz"
        public var description: String { return self.rawValue }
    }

    public enum AuthenticationType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case iam = "iam"
        case noPassword = "no-password"
        case password = "password"
        public var description: String { return self.rawValue }
    }

    public enum DataTieringStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case `false` = "false"
        case `true` = "true"
        public var description: String { return self.rawValue }
    }

    public enum InputAuthenticationType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case iam = "iam"
        case password = "password"
        public var description: String { return self.rawValue }
    }

    public enum IpDiscovery: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case ipv4 = "ipv4"
        case ipv6 = "ipv6"
        public var description: String { return self.rawValue }
    }

    public enum NetworkType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case dualStack = "dual_stack"
        case ipv4 = "ipv4"
        case ipv6 = "ipv6"
        public var description: String { return self.rawValue }
    }

    public enum ServiceUpdateStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case complete = "complete"
        case inProgress = "in-progress"
        case notApplied = "available"
        case scheduled = "scheduled"
        public var description: String { return self.rawValue }
    }

    public enum ServiceUpdateType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case securityUpdate = "security-update"
        public var description: String { return self.rawValue }
    }

    public enum SourceType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case acl = "acl"
        case cluster = "cluster"
        case node = "node"
        case parameterGroup = "parameter-group"
        case subnetGroup = "subnet-group"
        case user = "user"
        public var description: String { return self.rawValue }
    }

    public enum UpdateStrategy: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case coordinated = "coordinated"
        case uncoordinated = "uncoordinated"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct ACL: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the ACL
        public let arn: String?
        /// A list of clusters associated with the ACL.
        public let clusters: [String]?
        /// The minimum engine version supported for the ACL
        public let minimumEngineVersion: String?
        /// The name of the Access Control List
        public let name: String?
        /// A list of updates being applied to the ACL.
        public let pendingChanges: ACLPendingChanges?
        /// Indicates ACL status. Can be "creating", "active", "modifying", "deleting".
        public let status: String?
        /// The list of user names that belong to the ACL.
        public let userNames: [String]?

        @inlinable
        public init(arn: String? = nil, clusters: [String]? = nil, minimumEngineVersion: String? = nil, name: String? = nil, pendingChanges: ACLPendingChanges? = nil, status: String? = nil, userNames: [String]? = nil) {
            self.arn = arn
            self.clusters = clusters
            self.minimumEngineVersion = minimumEngineVersion
            self.name = name
            self.pendingChanges = pendingChanges
            self.status = status
            self.userNames = userNames
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "ARN"
            case clusters = "Clusters"
            case minimumEngineVersion = "MinimumEngineVersion"
            case name = "Name"
            case pendingChanges = "PendingChanges"
            case status = "Status"
            case userNames = "UserNames"
        }
    }

    public struct ACLPendingChanges: AWSDecodableShape {
        /// A list of users being added to the ACL
        public let userNamesToAdd: [String]?
        /// A list of user names being removed from the ACL
        public let userNamesToRemove: [String]?

        @inlinable
        public init(userNamesToAdd: [String]? = nil, userNamesToRemove: [String]? = nil) {
            self.userNamesToAdd = userNamesToAdd
            self.userNamesToRemove = userNamesToRemove
        }

        private enum CodingKeys: String, CodingKey {
            case userNamesToAdd = "UserNamesToAdd"
            case userNamesToRemove = "UserNamesToRemove"
        }
    }

    public struct ACLsUpdateStatus: AWSDecodableShape {
        /// A list of ACLs pending to be applied.
        public let aclToApply: String?

        @inlinable
        public init(aclToApply: String? = nil) {
            self.aclToApply = aclToApply
        }

        private enum CodingKeys: String, CodingKey {
            case aclToApply = "ACLToApply"
        }
    }

    public struct Authentication: AWSDecodableShape {
        /// The number of passwords belonging to the user. The maximum is two.
        public let passwordCount: Int?
        /// Indicates whether the user requires a password to authenticate.
        public let type: AuthenticationType?

        @inlinable
        public init(passwordCount: Int? = nil, type: AuthenticationType? = nil) {
            self.passwordCount = passwordCount
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case passwordCount = "PasswordCount"
            case type = "Type"
        }
    }

    public struct AuthenticationMode: AWSEncodableShape {
        /// The password(s) used for authentication
        public let passwords: [String]?
        /// Indicates whether the user requires a password to authenticate. All newly-created users require a password.
        public let type: InputAuthenticationType?

        @inlinable
        public init(passwords: [String]? = nil, type: InputAuthenticationType? = nil) {
            self.passwords = passwords
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.passwords, name: "passwords", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case passwords = "Passwords"
            case type = "Type"
        }
    }

    public struct AvailabilityZone: AWSDecodableShape {
        /// The name of the Availability Zone.
        public let name: String?

        @inlinable
        public init(name: String? = nil) {
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
        }
    }

    public struct BatchUpdateClusterRequest: AWSEncodableShape {
        /// The cluster names to apply the updates.
        public let clusterNames: [String]
        /// The unique ID of the service update
        public let serviceUpdate: ServiceUpdateRequest?

        @inlinable
        public init(clusterNames: [String], serviceUpdate: ServiceUpdateRequest? = nil) {
            self.clusterNames = clusterNames
            self.serviceUpdate = serviceUpdate
        }

        public func validate(name: String) throws {
            try self.validate(self.clusterNames, name: "clusterNames", parent: name, max: 20)
        }

        private enum CodingKeys: String, CodingKey {
            case clusterNames = "ClusterNames"
            case serviceUpdate = "ServiceUpdate"
        }
    }

    public struct BatchUpdateClusterResponse: AWSDecodableShape {
        /// The list of clusters that have been updated.
        public let processedClusters: [Cluster]?
        /// The list of clusters where updates have not been applied.
        public let unprocessedClusters: [UnprocessedCluster]?

        @inlinable
        public init(processedClusters: [Cluster]? = nil, unprocessedClusters: [UnprocessedCluster]? = nil) {
            self.processedClusters = processedClusters
            self.unprocessedClusters = unprocessedClusters
        }

        private enum CodingKeys: String, CodingKey {
            case processedClusters = "ProcessedClusters"
            case unprocessedClusters = "UnprocessedClusters"
        }
    }

    public struct Cluster: AWSDecodableShape {
        /// The name of the Access Control List associated with this cluster.
        public let aclName: String?
        /// The Amazon Resource Name (ARN) of the cluster.
        public let arn: String?
        /// When set to true, the cluster will automatically receive minor engine version upgrades after launch.
        public let autoMinorVersionUpgrade: Bool?
        /// Indicates if the cluster has a Multi-AZ configuration (multiaz) or not (singleaz).
        public let availabilityMode: AZStatus?
        /// The cluster's configuration endpoint
        public let clusterEndpoint: Endpoint?
        /// Enables data tiering. Data tiering is only supported for clusters using the r6gd node type.  This parameter must be set when using r6gd nodes. For more information, see Data tiering.
        public let dataTiering: DataTieringStatus?
        /// A description of the cluster
        public let description: String?
        /// The name of the engine used by the cluster.
        public let engine: String?
        /// The Redis OSS engine patch version used by the cluster
        public let enginePatchVersion: String?
        /// The Redis OSS engine version used by the cluster
        public let engineVersion: String?
        /// The mechanism that the cluster uses to discover IP addresses. Returns 'ipv4' when DNS endpoints resolve to IPv4 addresses, or 'ipv6' when DNS endpoints resolve to IPv6 addresses.
        public let ipDiscovery: IpDiscovery?
        /// The ID of the KMS key used to encrypt the cluster
        public let kmsKeyId: String?
        /// Specifies the weekly time range during which maintenance on the cluster is performed. It is specified as a range in the format ddd:hh24:mi-ddd:hh24:mi (24H Clock UTC). The minimum maintenance window is a 60 minute period.
        public let maintenanceWindow: String?
        /// The name of the multi-Region cluster that this cluster belongs to.
        public let multiRegionClusterName: String?
        /// The user-supplied name of the cluster. This identifier is a unique key that identifies a cluster.
        public let name: String?
        /// The IP address type for the cluster. Returns 'ipv4' for IPv4 only, 'ipv6' for IPv6 only, or 'dual-stack' if the cluster supports both IPv4 and IPv6 addressing.
        public let networkType: NetworkType?
        /// The cluster's node type
        public let nodeType: String?
        /// The number of shards in the cluster
        public let numberOfShards: Int?
        /// The name of the parameter group used by the cluster
        public let parameterGroupName: String?
        /// The status of the parameter group used by the cluster, for example 'active' or 'applying'.
        public let parameterGroupStatus: String?
        /// A group of settings that are currently being applied.
        public let pendingUpdates: ClusterPendingUpdates?
        /// A list of security groups used by the cluster
        public let securityGroups: [SecurityGroupMembership]?
        /// A list of shards that are members of the cluster.
        public let shards: [Shard]?
        /// The number of days for which MemoryDB retains automatic snapshots before deleting them. For example, if you set SnapshotRetentionLimit to 5, a snapshot that was taken today is retained for 5 days before being deleted.
        public let snapshotRetentionLimit: Int?
        /// The daily time range (in UTC) during which MemoryDB begins taking a daily snapshot of your shard.  Example: 05:00-09:00  If you do not specify this parameter, MemoryDB automatically chooses an appropriate time range.
        public let snapshotWindow: String?
        /// The Amazon Resource Name (ARN) of the SNS notification topic
        public let snsTopicArn: String?
        /// The SNS topic must be in Active status to receive notifications
        public let snsTopicStatus: String?
        /// The status of the cluster. For example, Available, Updating, Creating.
        public let status: String?
        /// The name of the subnet group used by the cluster
        public let subnetGroupName: String?
        /// A flag to indicate if In-transit encryption is enabled
        public let tlsEnabled: Bool?

        @inlinable
        public init(aclName: String? = nil, arn: String? = nil, autoMinorVersionUpgrade: Bool? = nil, availabilityMode: AZStatus? = nil, clusterEndpoint: Endpoint? = nil, dataTiering: DataTieringStatus? = nil, description: String? = nil, engine: String? = nil, enginePatchVersion: String? = nil, engineVersion: String? = nil, ipDiscovery: IpDiscovery? = nil, kmsKeyId: String? = nil, maintenanceWindow: String? = nil, multiRegionClusterName: String? = nil, name: String? = nil, networkType: NetworkType? = nil, nodeType: String? = nil, numberOfShards: Int? = nil, parameterGroupName: String? = nil, parameterGroupStatus: String? = nil, pendingUpdates: ClusterPendingUpdates? = nil, securityGroups: [SecurityGroupMembership]? = nil, shards: [Shard]? = nil, snapshotRetentionLimit: Int? = nil, snapshotWindow: String? = nil, snsTopicArn: String? = nil, snsTopicStatus: String? = nil, status: String? = nil, subnetGroupName: String? = nil, tlsEnabled: Bool? = nil) {
            self.aclName = aclName
            self.arn = arn
            self.autoMinorVersionUpgrade = autoMinorVersionUpgrade
            self.availabilityMode = availabilityMode
            self.clusterEndpoint = clusterEndpoint
            self.dataTiering = dataTiering
            self.description = description
            self.engine = engine
            self.enginePatchVersion = enginePatchVersion
            self.engineVersion = engineVersion
            self.ipDiscovery = ipDiscovery
            self.kmsKeyId = kmsKeyId
            self.maintenanceWindow = maintenanceWindow
            self.multiRegionClusterName = multiRegionClusterName
            self.name = name
            self.networkType = networkType
            self.nodeType = nodeType
            self.numberOfShards = numberOfShards
            self.parameterGroupName = parameterGroupName
            self.parameterGroupStatus = parameterGroupStatus
            self.pendingUpdates = pendingUpdates
            self.securityGroups = securityGroups
            self.shards = shards
            self.snapshotRetentionLimit = snapshotRetentionLimit
            self.snapshotWindow = snapshotWindow
            self.snsTopicArn = snsTopicArn
            self.snsTopicStatus = snsTopicStatus
            self.status = status
            self.subnetGroupName = subnetGroupName
            self.tlsEnabled = tlsEnabled
        }

        private enum CodingKeys: String, CodingKey {
            case aclName = "ACLName"
            case arn = "ARN"
            case autoMinorVersionUpgrade = "AutoMinorVersionUpgrade"
            case availabilityMode = "AvailabilityMode"
            case clusterEndpoint = "ClusterEndpoint"
            case dataTiering = "DataTiering"
            case description = "Description"
            case engine = "Engine"
            case enginePatchVersion = "EnginePatchVersion"
            case engineVersion = "EngineVersion"
            case ipDiscovery = "IpDiscovery"
            case kmsKeyId = "KmsKeyId"
            case maintenanceWindow = "MaintenanceWindow"
            case multiRegionClusterName = "MultiRegionClusterName"
            case name = "Name"
            case networkType = "NetworkType"
            case nodeType = "NodeType"
            case numberOfShards = "NumberOfShards"
            case parameterGroupName = "ParameterGroupName"
            case parameterGroupStatus = "ParameterGroupStatus"
            case pendingUpdates = "PendingUpdates"
            case securityGroups = "SecurityGroups"
            case shards = "Shards"
            case snapshotRetentionLimit = "SnapshotRetentionLimit"
            case snapshotWindow = "SnapshotWindow"
            case snsTopicArn = "SnsTopicArn"
            case snsTopicStatus = "SnsTopicStatus"
            case status = "Status"
            case subnetGroupName = "SubnetGroupName"
            case tlsEnabled = "TLSEnabled"
        }
    }

    public struct ClusterConfiguration: AWSDecodableShape {
        /// The description of the cluster configuration
        public let description: String?
        /// The name of the engine used by the cluster configuration.
        public let engine: String?
        /// The Redis OSS engine version used by the cluster
        public let engineVersion: String?
        /// The specified maintenance window for the cluster
        public let maintenanceWindow: String?
        /// The name for the multi-Region cluster associated with the cluster configuration.
        public let multiRegionClusterName: String?
        /// The name of the multi-Region parameter group associated with the cluster configuration.
        public let multiRegionParameterGroupName: String?
        /// The name of the cluster
        public let name: String?
        /// The node type used for the cluster
        public let nodeType: String?
        /// The number of shards in the cluster
        public let numShards: Int?
        /// The name of parameter group used by the cluster
        public let parameterGroupName: String?
        /// The port used by the cluster
        public let port: Int?
        /// The list of shards in the cluster
        public let shards: [ShardDetail]?
        /// The snapshot retention limit set by the cluster
        public let snapshotRetentionLimit: Int?
        /// The snapshot window set by the cluster
        public let snapshotWindow: String?
        /// The name of the subnet group used by the cluster
        public let subnetGroupName: String?
        /// The Amazon Resource Name (ARN) of the SNS notification topic for the cluster
        public let topicArn: String?
        /// The ID of the VPC the cluster belongs to
        public let vpcId: String?

        @inlinable
        public init(description: String? = nil, engine: String? = nil, engineVersion: String? = nil, maintenanceWindow: String? = nil, multiRegionClusterName: String? = nil, multiRegionParameterGroupName: String? = nil, name: String? = nil, nodeType: String? = nil, numShards: Int? = nil, parameterGroupName: String? = nil, port: Int? = nil, shards: [ShardDetail]? = nil, snapshotRetentionLimit: Int? = nil, snapshotWindow: String? = nil, subnetGroupName: String? = nil, topicArn: String? = nil, vpcId: String? = nil) {
            self.description = description
            self.engine = engine
            self.engineVersion = engineVersion
            self.maintenanceWindow = maintenanceWindow
            self.multiRegionClusterName = multiRegionClusterName
            self.multiRegionParameterGroupName = multiRegionParameterGroupName
            self.name = name
            self.nodeType = nodeType
            self.numShards = numShards
            self.parameterGroupName = parameterGroupName
            self.port = port
            self.shards = shards
            self.snapshotRetentionLimit = snapshotRetentionLimit
            self.snapshotWindow = snapshotWindow
            self.subnetGroupName = subnetGroupName
            self.topicArn = topicArn
            self.vpcId = vpcId
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case engine = "Engine"
            case engineVersion = "EngineVersion"
            case maintenanceWindow = "MaintenanceWindow"
            case multiRegionClusterName = "MultiRegionClusterName"
            case multiRegionParameterGroupName = "MultiRegionParameterGroupName"
            case name = "Name"
            case nodeType = "NodeType"
            case numShards = "NumShards"
            case parameterGroupName = "ParameterGroupName"
            case port = "Port"
            case shards = "Shards"
            case snapshotRetentionLimit = "SnapshotRetentionLimit"
            case snapshotWindow = "SnapshotWindow"
            case subnetGroupName = "SubnetGroupName"
            case topicArn = "TopicArn"
            case vpcId = "VpcId"
        }
    }

    public struct ClusterPendingUpdates: AWSDecodableShape {
        /// A list of ACLs associated with the cluster that are being updated
        public let acLs: ACLsUpdateStatus?
        /// The status of an online resharding operation.
        public let resharding: ReshardingStatus?
        /// A list of service updates being applied to the cluster
        public let serviceUpdates: [PendingModifiedServiceUpdate]?

        @inlinable
        public init(acLs: ACLsUpdateStatus? = nil, resharding: ReshardingStatus? = nil, serviceUpdates: [PendingModifiedServiceUpdate]? = nil) {
            self.acLs = acLs
            self.resharding = resharding
            self.serviceUpdates = serviceUpdates
        }

        private enum CodingKeys: String, CodingKey {
            case acLs = "ACLs"
            case resharding = "Resharding"
            case serviceUpdates = "ServiceUpdates"
        }
    }

    public struct CopySnapshotRequest: AWSEncodableShape {
        /// The ID of the KMS key used to encrypt the target snapshot.
        public let kmsKeyId: String?
        /// The name of an existing snapshot from which to make a copy.
        public let sourceSnapshotName: String
        /// A list of tags to be added to this resource. A tag is a key-value pair. A tag key must be accompanied by a tag value, although null is accepted.
        public let tags: [Tag]?
        /// The Amazon S3 bucket to which the snapshot is exported. This parameter is used only when exporting a snapshot for external access.  When using this parameter to export a snapshot, be sure MemoryDB has the needed permissions to this S3 bucket. For more information, see   Step 2: Grant MemoryDB Access to Your Amazon S3 Bucket.
        public let targetBucket: String?
        /// A name for the snapshot copy. MemoryDB does not permit overwriting a snapshot, therefore this name must be unique within its context - MemoryDB or an Amazon S3 bucket if exporting.
        public let targetSnapshotName: String

        @inlinable
        public init(kmsKeyId: String? = nil, sourceSnapshotName: String, tags: [Tag]? = nil, targetBucket: String? = nil, targetSnapshotName: String) {
            self.kmsKeyId = kmsKeyId
            self.sourceSnapshotName = sourceSnapshotName
            self.tags = tags
            self.targetBucket = targetBucket
            self.targetSnapshotName = targetSnapshotName
        }

        public func validate(name: String) throws {
            try self.validate(self.kmsKeyId, name: "kmsKeyId", parent: name, max: 2048)
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.validate(self.targetBucket, name: "targetBucket", parent: name, max: 255)
            try self.validate(self.targetBucket, name: "targetBucket", parent: name, pattern: "^[A-Za-z0-9._-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case kmsKeyId = "KmsKeyId"
            case sourceSnapshotName = "SourceSnapshotName"
            case tags = "Tags"
            case targetBucket = "TargetBucket"
            case targetSnapshotName = "TargetSnapshotName"
        }
    }

    public struct CopySnapshotResponse: AWSDecodableShape {
        /// Represents a copy of an entire cluster as of the time when the snapshot was taken.
        public let snapshot: Snapshot?

        @inlinable
        public init(snapshot: Snapshot? = nil) {
            self.snapshot = snapshot
        }

        private enum CodingKeys: String, CodingKey {
            case snapshot = "Snapshot"
        }
    }

    public struct CreateACLRequest: AWSEncodableShape {
        /// The name of the Access Control List.
        public let aclName: String
        /// A list of tags to be added to this resource. A tag is a key-value pair. A tag key must be accompanied by a tag value, although null is accepted.
        public let tags: [Tag]?
        /// The list of users that belong to the Access Control List.
        public let userNames: [String]?

        @inlinable
        public init(aclName: String, tags: [Tag]? = nil, userNames: [String]? = nil) {
            self.aclName = aclName
            self.tags = tags
            self.userNames = userNames
        }

        public func validate(name: String) throws {
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.userNames?.forEach {
                try validate($0, name: "userNames[]", parent: name, min: 1)
                try validate($0, name: "userNames[]", parent: name, pattern: "^[a-zA-Z][a-zA-Z0-9\\-]*$")
            }
            try self.validate(self.userNames, name: "userNames", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case aclName = "ACLName"
            case tags = "Tags"
            case userNames = "UserNames"
        }
    }

    public struct CreateACLResponse: AWSDecodableShape {
        /// The newly-created Access Control List.
        public let acl: ACL?

        @inlinable
        public init(acl: ACL? = nil) {
            self.acl = acl
        }

        private enum CodingKeys: String, CodingKey {
            case acl = "ACL"
        }
    }

    public struct CreateClusterRequest: AWSEncodableShape {
        /// The name of the Access Control List to associate with the cluster.
        public let aclName: String
        /// When set to true, the cluster will automatically receive minor engine version upgrades after launch.
        public let autoMinorVersionUpgrade: Bool?
        /// The name of the cluster. This value must be unique as it also serves as the cluster identifier.
        public let clusterName: String
        /// Enables data tiering. Data tiering is only supported for clusters using the r6gd node type.  This parameter must be set when using r6gd nodes. For more information, see Data tiering.
        public let dataTiering: Bool?
        /// An optional description of the cluster.
        public let description: String?
        /// The name of the engine to be used for the cluster.
        public let engine: String?
        /// The version number of the Redis OSS engine to be used for the cluster.
        public let engineVersion: String?
        /// The mechanism for discovering IP addresses for the cluster discovery protocol. Valid values are 'ipv4' or 'ipv6'. When set to 'ipv4', cluster discovery functions such as cluster slots, cluster shards, and cluster nodes return IPv4 addresses for cluster nodes. When set to 'ipv6', the cluster discovery functions return IPv6 addresses for cluster nodes. The value must be compatible with the NetworkType parameter. If not specified, the default is 'ipv4'.
        public let ipDiscovery: IpDiscovery?
        /// The ID of the KMS key used to encrypt the cluster.
        public let kmsKeyId: String?
        /// Specifies the weekly time range during which maintenance on the cluster is performed. It is specified as a range in the format ddd:hh24:mi-ddd:hh24:mi (24H Clock UTC). The minimum maintenance window is a 60 minute period. Valid values for ddd are:    sun     mon     tue     wed     thu     fri     sat    Example: sun:23:00-mon:01:30
        public let maintenanceWindow: String?
        /// The name of the multi-Region cluster to be created.
        public let multiRegionClusterName: String?
        /// Specifies the IP address type for the cluster. Valid values are 'ipv4', 'ipv6', or 'dual_stack'. When set to 'ipv4', the cluster will only be accessible via IPv4 addresses. When set to 'ipv6', the cluster will only be accessible via IPv6 addresses. When set to 'dual_stack', the cluster will be accessible via both IPv4 and IPv6 addresses. If not specified, the default is 'ipv4'.
        public let networkType: NetworkType?
        /// The compute and memory capacity of the nodes in the cluster.
        public let nodeType: String
        /// The number of replicas to apply to each shard. The default value is 1. The maximum is 5.
        public let numReplicasPerShard: Int?
        /// The number of shards the cluster will contain. The default value is 1.
        public let numShards: Int?
        /// The name of the parameter group associated with the cluster.
        public let parameterGroupName: String?
        /// The port number on which each of the nodes accepts connections.
        public let port: Int?
        /// A list of security group names to associate with this cluster.
        public let securityGroupIds: [String]?
        /// A list of Amazon Resource Names (ARN) that uniquely identify the RDB snapshot files stored in Amazon S3. The snapshot files are used to populate the new cluster. The Amazon S3 object name in the ARN cannot contain any commas.
        public let snapshotArns: [String]?
        /// The name of a snapshot from which to restore data into the new cluster. The snapshot status changes to restoring while the new cluster is being created.
        public let snapshotName: String?
        /// The number of days for which MemoryDB retains automatic snapshots before deleting them. For example, if you set SnapshotRetentionLimit to 5, a snapshot that was taken today is retained for 5 days before being deleted.
        public let snapshotRetentionLimit: Int?
        /// The daily time range (in UTC) during which MemoryDB begins taking a daily snapshot of your shard. Example: 05:00-09:00 If you do not specify this parameter, MemoryDB automatically chooses an appropriate time range.
        public let snapshotWindow: String?
        /// The Amazon Resource Name (ARN) of the Amazon Simple Notification Service (SNS) topic to which notifications are sent.
        public let snsTopicArn: String?
        /// The name of the subnet group to be used for the cluster.
        public let subnetGroupName: String?
        /// A list of tags to be added to this resource. Tags are comma-separated key,value pairs (e.g. Key=myKey, Value=myKeyValue. You can include multiple tags as shown following: Key=myKey, Value=myKeyValue Key=mySecondKey, Value=mySecondKeyValue.
        public let tags: [Tag]?
        /// A flag to enable in-transit encryption on the cluster.
        public let tlsEnabled: Bool?

        @inlinable
        public init(aclName: String, autoMinorVersionUpgrade: Bool? = nil, clusterName: String, dataTiering: Bool? = nil, description: String? = nil, engine: String? = nil, engineVersion: String? = nil, ipDiscovery: IpDiscovery? = nil, kmsKeyId: String? = nil, maintenanceWindow: String? = nil, multiRegionClusterName: String? = nil, networkType: NetworkType? = nil, nodeType: String, numReplicasPerShard: Int? = nil, numShards: Int? = nil, parameterGroupName: String? = nil, port: Int? = nil, securityGroupIds: [String]? = nil, snapshotArns: [String]? = nil, snapshotName: String? = nil, snapshotRetentionLimit: Int? = nil, snapshotWindow: String? = nil, snsTopicArn: String? = nil, subnetGroupName: String? = nil, tags: [Tag]? = nil, tlsEnabled: Bool? = nil) {
            self.aclName = aclName
            self.autoMinorVersionUpgrade = autoMinorVersionUpgrade
            self.clusterName = clusterName
            self.dataTiering = dataTiering
            self.description = description
            self.engine = engine
            self.engineVersion = engineVersion
            self.ipDiscovery = ipDiscovery
            self.kmsKeyId = kmsKeyId
            self.maintenanceWindow = maintenanceWindow
            self.multiRegionClusterName = multiRegionClusterName
            self.networkType = networkType
            self.nodeType = nodeType
            self.numReplicasPerShard = numReplicasPerShard
            self.numShards = numShards
            self.parameterGroupName = parameterGroupName
            self.port = port
            self.securityGroupIds = securityGroupIds
            self.snapshotArns = snapshotArns
            self.snapshotName = snapshotName
            self.snapshotRetentionLimit = snapshotRetentionLimit
            self.snapshotWindow = snapshotWindow
            self.snsTopicArn = snsTopicArn
            self.subnetGroupName = subnetGroupName
            self.tags = tags
            self.tlsEnabled = tlsEnabled
        }

        public func validate(name: String) throws {
            try self.validate(self.aclName, name: "aclName", parent: name, min: 1)
            try self.validate(self.aclName, name: "aclName", parent: name, pattern: "^[a-zA-Z][a-zA-Z0-9\\-]*$")
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case aclName = "ACLName"
            case autoMinorVersionUpgrade = "AutoMinorVersionUpgrade"
            case clusterName = "ClusterName"
            case dataTiering = "DataTiering"
            case description = "Description"
            case engine = "Engine"
            case engineVersion = "EngineVersion"
            case ipDiscovery = "IpDiscovery"
            case kmsKeyId = "KmsKeyId"
            case maintenanceWindow = "MaintenanceWindow"
            case multiRegionClusterName = "MultiRegionClusterName"
            case networkType = "NetworkType"
            case nodeType = "NodeType"
            case numReplicasPerShard = "NumReplicasPerShard"
            case numShards = "NumShards"
            case parameterGroupName = "ParameterGroupName"
            case port = "Port"
            case securityGroupIds = "SecurityGroupIds"
            case snapshotArns = "SnapshotArns"
            case snapshotName = "SnapshotName"
            case snapshotRetentionLimit = "SnapshotRetentionLimit"
            case snapshotWindow = "SnapshotWindow"
            case snsTopicArn = "SnsTopicArn"
            case subnetGroupName = "SubnetGroupName"
            case tags = "Tags"
            case tlsEnabled = "TLSEnabled"
        }
    }

    public struct CreateClusterResponse: AWSDecodableShape {
        /// The newly-created cluster.
        public let cluster: Cluster?

        @inlinable
        public init(cluster: Cluster? = nil) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "Cluster"
        }
    }

    public struct CreateMultiRegionClusterRequest: AWSEncodableShape {
        /// A description for the multi-Region cluster.
        public let description: String?
        /// The name of the engine to be used for the multi-Region cluster.
        public let engine: String?
        /// The version of the engine to be used for the multi-Region cluster.
        public let engineVersion: String?
        /// A suffix to be added to the Multi-Region cluster name. Amazon MemoryDB automatically applies a prefix to the Multi-Region cluster Name when it is created. Each Amazon Region has its own prefix. For instance, a Multi-Region cluster Name created in the US-West-1 region will begin with "virxk", along with the suffix name you provide. The suffix guarantees uniqueness of the Multi-Region cluster name across multiple regions.
        public let multiRegionClusterNameSuffix: String
        /// The name of the multi-Region parameter group to be associated with the cluster.
        public let multiRegionParameterGroupName: String?
        /// The node type to be used for the multi-Region cluster.
        public let nodeType: String
        /// The number of shards for the multi-Region cluster.
        public let numShards: Int?
        /// A list of tags to be applied to the multi-Region cluster.
        public let tags: [Tag]?
        /// Whether to enable TLS encryption for the multi-Region cluster.
        public let tlsEnabled: Bool?

        @inlinable
        public init(description: String? = nil, engine: String? = nil, engineVersion: String? = nil, multiRegionClusterNameSuffix: String, multiRegionParameterGroupName: String? = nil, nodeType: String, numShards: Int? = nil, tags: [Tag]? = nil, tlsEnabled: Bool? = nil) {
            self.description = description
            self.engine = engine
            self.engineVersion = engineVersion
            self.multiRegionClusterNameSuffix = multiRegionClusterNameSuffix
            self.multiRegionParameterGroupName = multiRegionParameterGroupName
            self.nodeType = nodeType
            self.numShards = numShards
            self.tags = tags
            self.tlsEnabled = tlsEnabled
        }

        public func validate(name: String) throws {
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case engine = "Engine"
            case engineVersion = "EngineVersion"
            case multiRegionClusterNameSuffix = "MultiRegionClusterNameSuffix"
            case multiRegionParameterGroupName = "MultiRegionParameterGroupName"
            case nodeType = "NodeType"
            case numShards = "NumShards"
            case tags = "Tags"
            case tlsEnabled = "TLSEnabled"
        }
    }

    public struct CreateMultiRegionClusterResponse: AWSDecodableShape {
        /// Details about the newly created multi-Region cluster.
        public let multiRegionCluster: MultiRegionCluster?

        @inlinable
        public init(multiRegionCluster: MultiRegionCluster? = nil) {
            self.multiRegionCluster = multiRegionCluster
        }

        private enum CodingKeys: String, CodingKey {
            case multiRegionCluster = "MultiRegionCluster"
        }
    }

    public struct CreateParameterGroupRequest: AWSEncodableShape {
        /// An optional description of the parameter group.
        public let description: String?
        /// The name of the parameter group family that the parameter group can be used with.
        public let family: String
        /// The name of the parameter group.
        public let parameterGroupName: String
        /// A list of tags to be added to this resource. A tag is a key-value pair. A tag key must be accompanied by a tag value, although null is accepted.
        public let tags: [Tag]?

        @inlinable
        public init(description: String? = nil, family: String, parameterGroupName: String, tags: [Tag]? = nil) {
            self.description = description
            self.family = family
            self.parameterGroupName = parameterGroupName
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case family = "Family"
            case parameterGroupName = "ParameterGroupName"
            case tags = "Tags"
        }
    }

    public struct CreateParameterGroupResponse: AWSDecodableShape {
        /// The newly-created parameter group.
        public let parameterGroup: ParameterGroup?

        @inlinable
        public init(parameterGroup: ParameterGroup? = nil) {
            self.parameterGroup = parameterGroup
        }

        private enum CodingKeys: String, CodingKey {
            case parameterGroup = "ParameterGroup"
        }
    }

    public struct CreateSnapshotRequest: AWSEncodableShape {
        /// The snapshot is created from this cluster.
        public let clusterName: String
        /// The ID of the KMS key used to encrypt the snapshot.
        public let kmsKeyId: String?
        /// A name for the snapshot being created.
        public let snapshotName: String
        /// A list of tags to be added to this resource. A tag is a key-value pair. A tag key must be accompanied by a tag value, although null is accepted.
        public let tags: [Tag]?

        @inlinable
        public init(clusterName: String, kmsKeyId: String? = nil, snapshotName: String, tags: [Tag]? = nil) {
            self.clusterName = clusterName
            self.kmsKeyId = kmsKeyId
            self.snapshotName = snapshotName
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case clusterName = "ClusterName"
            case kmsKeyId = "KmsKeyId"
            case snapshotName = "SnapshotName"
            case tags = "Tags"
        }
    }

    public struct CreateSnapshotResponse: AWSDecodableShape {
        /// The newly-created snapshot.
        public let snapshot: Snapshot?

        @inlinable
        public init(snapshot: Snapshot? = nil) {
            self.snapshot = snapshot
        }

        private enum CodingKeys: String, CodingKey {
            case snapshot = "Snapshot"
        }
    }

    public struct CreateSubnetGroupRequest: AWSEncodableShape {
        /// A description for the subnet group.
        public let description: String?
        /// The name of the subnet group.
        public let subnetGroupName: String
        /// A list of VPC subnet IDs for the subnet group.
        public let subnetIds: [String]
        /// A list of tags to be added to this resource. A tag is a key-value pair. A tag key must be accompanied by a tag value, although null is accepted.
        public let tags: [Tag]?

        @inlinable
        public init(description: String? = nil, subnetGroupName: String, subnetIds: [String], tags: [Tag]? = nil) {
            self.description = description
            self.subnetGroupName = subnetGroupName
            self.subnetIds = subnetIds
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case subnetGroupName = "SubnetGroupName"
            case subnetIds = "SubnetIds"
            case tags = "Tags"
        }
    }

    public struct CreateSubnetGroupResponse: AWSDecodableShape {
        /// The newly-created subnet group.
        public let subnetGroup: SubnetGroup?

        @inlinable
        public init(subnetGroup: SubnetGroup? = nil) {
            self.subnetGroup = subnetGroup
        }

        private enum CodingKeys: String, CodingKey {
            case subnetGroup = "SubnetGroup"
        }
    }

    public struct CreateUserRequest: AWSEncodableShape {
        /// Access permissions string used for this user.
        public let accessString: String
        /// Denotes the user's authentication properties, such as whether it requires a password to authenticate.
        public let authenticationMode: AuthenticationMode
        /// A list of tags to be added to this resource. A tag is a key-value pair. A tag key must be accompanied by a tag value, although null is accepted.
        public let tags: [Tag]?
        /// The name of the user. This value must be unique as it also serves as the user identifier.
        public let userName: String

        @inlinable
        public init(accessString: String, authenticationMode: AuthenticationMode, tags: [Tag]? = nil, userName: String) {
            self.accessString = accessString
            self.authenticationMode = authenticationMode
            self.tags = tags
            self.userName = userName
        }

        public func validate(name: String) throws {
            try self.validate(self.accessString, name: "accessString", parent: name, pattern: "\\S")
            try self.authenticationMode.validate(name: "\(name).authenticationMode")
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.validate(self.userName, name: "userName", parent: name, min: 1)
            try self.validate(self.userName, name: "userName", parent: name, pattern: "^[a-zA-Z][a-zA-Z0-9\\-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case accessString = "AccessString"
            case authenticationMode = "AuthenticationMode"
            case tags = "Tags"
            case userName = "UserName"
        }
    }

    public struct CreateUserResponse: AWSDecodableShape {
        /// The newly-created user.
        public let user: User?

        @inlinable
        public init(user: User? = nil) {
            self.user = user
        }

        private enum CodingKeys: String, CodingKey {
            case user = "User"
        }
    }

    public struct DeleteACLRequest: AWSEncodableShape {
        /// The name of the Access Control List to delete.
        public let aclName: String

        @inlinable
        public init(aclName: String) {
            self.aclName = aclName
        }

        private enum CodingKeys: String, CodingKey {
            case aclName = "ACLName"
        }
    }

    public struct DeleteACLResponse: AWSDecodableShape {
        /// The Access Control List object that has been deleted.
        public let acl: ACL?

        @inlinable
        public init(acl: ACL? = nil) {
            self.acl = acl
        }

        private enum CodingKeys: String, CodingKey {
            case acl = "ACL"
        }
    }

    public struct DeleteClusterRequest: AWSEncodableShape {
        /// The name of the cluster to be deleted
        public let clusterName: String
        /// The user-supplied name of a final cluster snapshot. This is the unique name that identifies the snapshot. MemoryDB creates the snapshot, and then deletes the cluster immediately afterward.
        public let finalSnapshotName: String?
        /// The name of the multi-Region cluster to be deleted.
        public let multiRegionClusterName: String?

        @inlinable
        public init(clusterName: String, finalSnapshotName: String? = nil, multiRegionClusterName: String? = nil) {
            self.clusterName = clusterName
            self.finalSnapshotName = finalSnapshotName
            self.multiRegionClusterName = multiRegionClusterName
        }

        private enum CodingKeys: String, CodingKey {
            case clusterName = "ClusterName"
            case finalSnapshotName = "FinalSnapshotName"
            case multiRegionClusterName = "MultiRegionClusterName"
        }
    }

    public struct DeleteClusterResponse: AWSDecodableShape {
        /// The cluster object that has been deleted.
        public let cluster: Cluster?

        @inlinable
        public init(cluster: Cluster? = nil) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "Cluster"
        }
    }

    public struct DeleteMultiRegionClusterRequest: AWSEncodableShape {
        /// The name of the multi-Region cluster to be deleted.
        public let multiRegionClusterName: String

        @inlinable
        public init(multiRegionClusterName: String) {
            self.multiRegionClusterName = multiRegionClusterName
        }

        private enum CodingKeys: String, CodingKey {
            case multiRegionClusterName = "MultiRegionClusterName"
        }
    }

    public struct DeleteMultiRegionClusterResponse: AWSDecodableShape {
        /// Details about the deleted multi-Region cluster.
        public let multiRegionCluster: MultiRegionCluster?

        @inlinable
        public init(multiRegionCluster: MultiRegionCluster? = nil) {
            self.multiRegionCluster = multiRegionCluster
        }

        private enum CodingKeys: String, CodingKey {
            case multiRegionCluster = "MultiRegionCluster"
        }
    }

    public struct DeleteParameterGroupRequest: AWSEncodableShape {
        /// The name of the parameter group to delete.
        public let parameterGroupName: String

        @inlinable
        public init(parameterGroupName: String) {
            self.parameterGroupName = parameterGroupName
        }

        private enum CodingKeys: String, CodingKey {
            case parameterGroupName = "ParameterGroupName"
        }
    }

    public struct DeleteParameterGroupResponse: AWSDecodableShape {
        /// The parameter group that has been deleted.
        public let parameterGroup: ParameterGroup?

        @inlinable
        public init(parameterGroup: ParameterGroup? = nil) {
            self.parameterGroup = parameterGroup
        }

        private enum CodingKeys: String, CodingKey {
            case parameterGroup = "ParameterGroup"
        }
    }

    public struct DeleteSnapshotRequest: AWSEncodableShape {
        /// The name of the snapshot to delete.
        public let snapshotName: String

        @inlinable
        public init(snapshotName: String) {
            self.snapshotName = snapshotName
        }

        private enum CodingKeys: String, CodingKey {
            case snapshotName = "SnapshotName"
        }
    }

    public struct DeleteSnapshotResponse: AWSDecodableShape {
        /// The snapshot object that has been deleted.
        public let snapshot: Snapshot?

        @inlinable
        public init(snapshot: Snapshot? = nil) {
            self.snapshot = snapshot
        }

        private enum CodingKeys: String, CodingKey {
            case snapshot = "Snapshot"
        }
    }

    public struct DeleteSubnetGroupRequest: AWSEncodableShape {
        /// The name of the subnet group to delete.
        public let subnetGroupName: String

        @inlinable
        public init(subnetGroupName: String) {
            self.subnetGroupName = subnetGroupName
        }

        private enum CodingKeys: String, CodingKey {
            case subnetGroupName = "SubnetGroupName"
        }
    }

    public struct DeleteSubnetGroupResponse: AWSDecodableShape {
        /// The subnet group object that has been deleted.
        public let subnetGroup: SubnetGroup?

        @inlinable
        public init(subnetGroup: SubnetGroup? = nil) {
            self.subnetGroup = subnetGroup
        }

        private enum CodingKeys: String, CodingKey {
            case subnetGroup = "SubnetGroup"
        }
    }

    public struct DeleteUserRequest: AWSEncodableShape {
        /// The name of the user to delete
        public let userName: String

        @inlinable
        public init(userName: String) {
            self.userName = userName
        }

        public func validate(name: String) throws {
            try self.validate(self.userName, name: "userName", parent: name, min: 1)
            try self.validate(self.userName, name: "userName", parent: name, pattern: "^[a-zA-Z][a-zA-Z0-9\\-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case userName = "UserName"
        }
    }

    public struct DeleteUserResponse: AWSDecodableShape {
        /// The user object that has been deleted.
        public let user: User?

        @inlinable
        public init(user: User? = nil) {
            self.user = user
        }

        private enum CodingKeys: String, CodingKey {
            case user = "User"
        }
    }

    public struct DescribeACLsRequest: AWSEncodableShape {
        /// The name of the ACL.
        public let aclName: String?
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?

        @inlinable
        public init(aclName: String? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.aclName = aclName
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case aclName = "ACLName"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct DescribeACLsResponse: AWSDecodableShape {
        /// The list of ACLs.
        public let acLs: [ACL]?
        /// If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?

        @inlinable
        public init(acLs: [ACL]? = nil, nextToken: String? = nil) {
            self.acLs = acLs
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case acLs = "ACLs"
            case nextToken = "NextToken"
        }
    }

    public struct DescribeClustersRequest: AWSEncodableShape {
        /// The name of the cluster.
        public let clusterName: String?
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// An optional flag that can be included in the request to retrieve information about the individual shard(s).
        public let showShardDetails: Bool?

        @inlinable
        public init(clusterName: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, showShardDetails: Bool? = nil) {
            self.clusterName = clusterName
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.showShardDetails = showShardDetails
        }

        private enum CodingKeys: String, CodingKey {
            case clusterName = "ClusterName"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case showShardDetails = "ShowShardDetails"
        }
    }

    public struct DescribeClustersResponse: AWSDecodableShape {
        /// A list of clusters
        public let clusters: [Cluster]?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?

        @inlinable
        public init(clusters: [Cluster]? = nil, nextToken: String? = nil) {
            self.clusters = clusters
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case clusters = "Clusters"
            case nextToken = "NextToken"
        }
    }

    public struct DescribeEngineVersionsRequest: AWSEncodableShape {
        /// If true, specifies that only the default version of the specified engine or engine and major version combination is to be returned.
        public let defaultOnly: Bool?
        /// The name of the engine for which to list available versions.
        public let engine: String?
        /// The Redis OSS engine version
        public let engineVersion: String?
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// The name of a specific parameter group family to return details for.
        public let parameterGroupFamily: String?

        @inlinable
        public init(defaultOnly: Bool? = nil, engine: String? = nil, engineVersion: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, parameterGroupFamily: String? = nil) {
            self.defaultOnly = defaultOnly
            self.engine = engine
            self.engineVersion = engineVersion
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.parameterGroupFamily = parameterGroupFamily
        }

        private enum CodingKeys: String, CodingKey {
            case defaultOnly = "DefaultOnly"
            case engine = "Engine"
            case engineVersion = "EngineVersion"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case parameterGroupFamily = "ParameterGroupFamily"
        }
    }

    public struct DescribeEngineVersionsResponse: AWSDecodableShape {
        /// A list of engine version details. Each element in the list contains detailed information about one engine version.
        public let engineVersions: [EngineVersionInfo]?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?

        @inlinable
        public init(engineVersions: [EngineVersionInfo]? = nil, nextToken: String? = nil) {
            self.engineVersions = engineVersions
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case engineVersions = "EngineVersions"
            case nextToken = "NextToken"
        }
    }

    public struct DescribeEventsRequest: AWSEncodableShape {
        /// The number of minutes worth of events to retrieve.
        public let duration: Int?
        /// The end of the time interval for which to retrieve events, specified in ISO 8601 format.  Example: 2017-03-30T07:03:49.555Z
        public let endTime: Date?
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// The identifier of the event source for which events are returned. If not specified, all sources are included in the response.
        public let sourceName: String?
        /// The event source to retrieve events for. If no value is specified, all events are returned.
        public let sourceType: SourceType?
        /// The beginning of the time interval to retrieve events for, specified in ISO 8601 format.  Example: 2017-03-30T07:03:49.555Z
        public let startTime: Date?

        @inlinable
        public init(duration: Int? = nil, endTime: Date? = nil, maxResults: Int? = nil, nextToken: String? = nil, sourceName: String? = nil, sourceType: SourceType? = nil, startTime: Date? = nil) {
            self.duration = duration
            self.endTime = endTime
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.sourceName = sourceName
            self.sourceType = sourceType
            self.startTime = startTime
        }

        private enum CodingKeys: String, CodingKey {
            case duration = "Duration"
            case endTime = "EndTime"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case sourceName = "SourceName"
            case sourceType = "SourceType"
            case startTime = "StartTime"
        }
    }

    public struct DescribeEventsResponse: AWSDecodableShape {
        /// A list of events. Each element in the list contains detailed information about one event.
        public let events: [Event]?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?

        @inlinable
        public init(events: [Event]? = nil, nextToken: String? = nil) {
            self.events = events
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case events = "Events"
            case nextToken = "NextToken"
        }
    }

    public struct DescribeMultiRegionClustersRequest: AWSEncodableShape {
        /// The maximum number of results to return.
        public let maxResults: Int?
        /// The name of a specific multi-Region cluster to describe.
        public let multiRegionClusterName: String?
        /// A token to specify where to start paginating.
        public let nextToken: String?
        /// Details about the multi-Region cluster.
        public let showClusterDetails: Bool?

        @inlinable
        public init(maxResults: Int? = nil, multiRegionClusterName: String? = nil, nextToken: String? = nil, showClusterDetails: Bool? = nil) {
            self.maxResults = maxResults
            self.multiRegionClusterName = multiRegionClusterName
            self.nextToken = nextToken
            self.showClusterDetails = showClusterDetails
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case multiRegionClusterName = "MultiRegionClusterName"
            case nextToken = "NextToken"
            case showClusterDetails = "ShowClusterDetails"
        }
    }

    public struct DescribeMultiRegionClustersResponse: AWSDecodableShape {
        /// A list of multi-Region clusters.
        public let multiRegionClusters: [MultiRegionCluster]?
        /// A token to use to retrieve the next page of results.
        public let nextToken: String?

        @inlinable
        public init(multiRegionClusters: [MultiRegionCluster]? = nil, nextToken: String? = nil) {
            self.multiRegionClusters = multiRegionClusters
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case multiRegionClusters = "MultiRegionClusters"
            case nextToken = "NextToken"
        }
    }

    public struct DescribeParameterGroupsRequest: AWSEncodableShape {
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// The name of a specific  parameter group to return details for.
        public let parameterGroupName: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, parameterGroupName: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.parameterGroupName = parameterGroupName
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case parameterGroupName = "ParameterGroupName"
        }
    }

    public struct DescribeParameterGroupsResponse: AWSDecodableShape {
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// A list of parameter groups. Each element in the list contains detailed information about one parameter group.
        public let parameterGroups: [ParameterGroup]?

        @inlinable
        public init(nextToken: String? = nil, parameterGroups: [ParameterGroup]? = nil) {
            self.nextToken = nextToken
            self.parameterGroups = parameterGroups
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case parameterGroups = "ParameterGroups"
        }
    }

    public struct DescribeParametersRequest: AWSEncodableShape {
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// he name of a specific  parameter group to return details for.
        public let parameterGroupName: String

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, parameterGroupName: String) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.parameterGroupName = parameterGroupName
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case parameterGroupName = "ParameterGroupName"
        }
    }

    public struct DescribeParametersResponse: AWSDecodableShape {
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// A list of parameters specific to a particular parameter group. Each element in the list contains detailed information about one parameter.
        public let parameters: [Parameter]?

        @inlinable
        public init(nextToken: String? = nil, parameters: [Parameter]? = nil) {
            self.nextToken = nextToken
            self.parameters = parameters
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case parameters = "Parameters"
        }
    }

    public struct DescribeReservedNodesOfferingsRequest: AWSEncodableShape {
        /// Duration filter value, specified in years or seconds. Use this parameter to show only reservations for a given duration.
        public let duration: String?
        /// The maximum number of records to include in the response. If more records exist than the specified MaxRecords value, a marker is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional marker returned from a prior request. Use this marker for pagination of results from this operation. If this parameter is specified, the response includes only records beyond the marker, up to the value specified by MaxRecords.
        public let nextToken: String?
        /// The node type for the reserved nodes. For more information, see Supported node types.
        public let nodeType: String?
        /// The offering type filter value. Use this parameter to show only the available offerings matching the specified offering type.  Valid values: "All Upfront"|"Partial Upfront"| "No Upfront"
        public let offeringType: String?
        /// The offering identifier filter value. Use this parameter to show only the available offering that matches the specified reservation identifier.
        public let reservedNodesOfferingId: String?

        @inlinable
        public init(duration: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, nodeType: String? = nil, offeringType: String? = nil, reservedNodesOfferingId: String? = nil) {
            self.duration = duration
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.nodeType = nodeType
            self.offeringType = offeringType
            self.reservedNodesOfferingId = reservedNodesOfferingId
        }

        private enum CodingKeys: String, CodingKey {
            case duration = "Duration"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case nodeType = "NodeType"
            case offeringType = "OfferingType"
            case reservedNodesOfferingId = "ReservedNodesOfferingId"
        }
    }

    public struct DescribeReservedNodesOfferingsResponse: AWSDecodableShape {
        /// An optional marker returned from a prior request. Use this marker for pagination of results from this operation. If this parameter is specified, the response includes only records beyond the marker, up to the value specified by MaxRecords.
        public let nextToken: String?
        /// Lists available reserved node offerings.
        public let reservedNodesOfferings: [ReservedNodesOffering]?

        @inlinable
        public init(nextToken: String? = nil, reservedNodesOfferings: [ReservedNodesOffering]? = nil) {
            self.nextToken = nextToken
            self.reservedNodesOfferings = reservedNodesOfferings
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case reservedNodesOfferings = "ReservedNodesOfferings"
        }
    }

    public struct DescribeReservedNodesRequest: AWSEncodableShape {
        /// The duration filter value, specified in years or seconds. Use this parameter to show only reservations for this duration.
        public let duration: String?
        /// The maximum number of records to include in the response. If more records exist than the specified MaxRecords value, a marker is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional marker returned from a prior request. Use this marker for pagination of results from this operation. If this parameter is specified, the response includes only records beyond the marker, up to the value specified by MaxRecords.
        public let nextToken: String?
        /// The node type filter value. Use this parameter to show only those reservations matching the specified  node type. For more information, see Supported node types.
        public let nodeType: String?
        /// The offering type filter value. Use this parameter to show only the available offerings matching the specified offering type.  Valid values: "All Upfront"|"Partial Upfront"| "No Upfront"
        public let offeringType: String?
        /// The reserved node identifier filter value. Use this parameter to show only the reservation that matches the specified reservation ID.
        public let reservationId: String?
        /// The offering identifier filter value. Use this parameter to show only purchased reservations matching the specified offering identifier.
        public let reservedNodesOfferingId: String?

        @inlinable
        public init(duration: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, nodeType: String? = nil, offeringType: String? = nil, reservationId: String? = nil, reservedNodesOfferingId: String? = nil) {
            self.duration = duration
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.nodeType = nodeType
            self.offeringType = offeringType
            self.reservationId = reservationId
            self.reservedNodesOfferingId = reservedNodesOfferingId
        }

        private enum CodingKeys: String, CodingKey {
            case duration = "Duration"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case nodeType = "NodeType"
            case offeringType = "OfferingType"
            case reservationId = "ReservationId"
            case reservedNodesOfferingId = "ReservedNodesOfferingId"
        }
    }

    public struct DescribeReservedNodesResponse: AWSDecodableShape {
        /// An optional marker returned from a prior request. Use this marker for pagination of results from this operation. If this parameter is specified, the response includes only records beyond the marker, up to the value specified by MaxRecords.
        public let nextToken: String?
        /// Returns information about reserved nodes for this account, or about a specified reserved node.
        public let reservedNodes: [ReservedNode]?

        @inlinable
        public init(nextToken: String? = nil, reservedNodes: [ReservedNode]? = nil) {
            self.nextToken = nextToken
            self.reservedNodes = reservedNodes
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case reservedNodes = "ReservedNodes"
        }
    }

    public struct DescribeServiceUpdatesRequest: AWSEncodableShape {
        /// The list of cluster names to identify service updates to apply.
        public let clusterNames: [String]?
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// The unique ID of the service update to describe.
        public let serviceUpdateName: String?
        /// The status(es) of the service updates to filter on.
        public let status: [ServiceUpdateStatus]?

        @inlinable
        public init(clusterNames: [String]? = nil, maxResults: Int? = nil, nextToken: String? = nil, serviceUpdateName: String? = nil, status: [ServiceUpdateStatus]? = nil) {
            self.clusterNames = clusterNames
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.serviceUpdateName = serviceUpdateName
            self.status = status
        }

        public func validate(name: String) throws {
            try self.validate(self.clusterNames, name: "clusterNames", parent: name, max: 20)
            try self.validate(self.status, name: "status", parent: name, max: 4)
        }

        private enum CodingKeys: String, CodingKey {
            case clusterNames = "ClusterNames"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case serviceUpdateName = "ServiceUpdateName"
            case status = "Status"
        }
    }

    public struct DescribeServiceUpdatesResponse: AWSDecodableShape {
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// A list of service updates
        public let serviceUpdates: [ServiceUpdate]?

        @inlinable
        public init(nextToken: String? = nil, serviceUpdates: [ServiceUpdate]? = nil) {
            self.nextToken = nextToken
            self.serviceUpdates = serviceUpdates
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case serviceUpdates = "ServiceUpdates"
        }
    }

    public struct DescribeSnapshotsRequest: AWSEncodableShape {
        /// A user-supplied cluster identifier. If this parameter is specified, only snapshots associated with that specific cluster are described.
        public let clusterName: String?
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// A Boolean value which if true, the shard configuration is included in the snapshot description.
        public let showDetail: Bool?
        /// A user-supplied name of the snapshot. If this parameter is specified, only this named snapshot is described.
        public let snapshotName: String?
        /// If set to system, the output shows snapshots that were automatically created by MemoryDB. If set to user the output shows snapshots that were manually created. If omitted, the output shows both automatically and manually created snapshots.
        public let source: String?

        @inlinable
        public init(clusterName: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, showDetail: Bool? = nil, snapshotName: String? = nil, source: String? = nil) {
            self.clusterName = clusterName
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.showDetail = showDetail
            self.snapshotName = snapshotName
            self.source = source
        }

        private enum CodingKeys: String, CodingKey {
            case clusterName = "ClusterName"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case showDetail = "ShowDetail"
            case snapshotName = "SnapshotName"
            case source = "Source"
        }
    }

    public struct DescribeSnapshotsResponse: AWSDecodableShape {
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// A list of snapshots. Each item in the list contains detailed information about one snapshot.
        public let snapshots: [Snapshot]?

        @inlinable
        public init(nextToken: String? = nil, snapshots: [Snapshot]? = nil) {
            self.nextToken = nextToken
            self.snapshots = snapshots
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case snapshots = "Snapshots"
        }
    }

    public struct DescribeSubnetGroupsRequest: AWSEncodableShape {
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// The name of the subnet group to return details for.
        public let subnetGroupName: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, subnetGroupName: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.subnetGroupName = subnetGroupName
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case subnetGroupName = "SubnetGroupName"
        }
    }

    public struct DescribeSubnetGroupsResponse: AWSDecodableShape {
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// A list of subnet groups. Each element in the list contains detailed information about one group.
        public let subnetGroups: [SubnetGroup]?

        @inlinable
        public init(nextToken: String? = nil, subnetGroups: [SubnetGroup]? = nil) {
            self.nextToken = nextToken
            self.subnetGroups = subnetGroups
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case subnetGroups = "SubnetGroups"
        }
    }

    public struct DescribeUsersRequest: AWSEncodableShape {
        /// Filter to determine the list of users to return.
        public let filters: [Filter]?
        /// The maximum number of records to include in the response. If more records exist than the specified MaxResults value, a token is included in the response so that the remaining results can be retrieved.
        public let maxResults: Int?
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// The name of the user.
        public let userName: String?

        @inlinable
        public init(filters: [Filter]? = nil, maxResults: Int? = nil, nextToken: String? = nil, userName: String? = nil) {
            self.filters = filters
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.userName = userName
        }

        public func validate(name: String) throws {
            try self.filters?.forEach {
                try $0.validate(name: "\(name).filters[]")
            }
            try self.validate(self.userName, name: "userName", parent: name, min: 1)
            try self.validate(self.userName, name: "userName", parent: name, pattern: "^[a-zA-Z][a-zA-Z0-9\\-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case filters = "Filters"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case userName = "UserName"
        }
    }

    public struct DescribeUsersResponse: AWSDecodableShape {
        /// An optional argument to pass in case the total number of records exceeds the value of MaxResults. If nextToken is returned, there are more results available. The value of nextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged.
        public let nextToken: String?
        /// A list of users.
        public let users: [User]?

        @inlinable
        public init(nextToken: String? = nil, users: [User]? = nil) {
            self.nextToken = nextToken
            self.users = users
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case users = "Users"
        }
    }

    public struct Endpoint: AWSDecodableShape {
        /// The DNS hostname of the node.
        public let address: String?
        /// The port number that the engine is listening on.
        public let port: Int?

        @inlinable
        public init(address: String? = nil, port: Int? = nil) {
            self.address = address
            self.port = port
        }

        private enum CodingKeys: String, CodingKey {
            case address = "Address"
            case port = "Port"
        }
    }

    public struct EngineVersionInfo: AWSDecodableShape {
        /// The name of the engine for which version information is provided.
        public let engine: String?
        /// The patched engine version
        public let enginePatchVersion: String?
        /// The engine version
        public let engineVersion: String?
        /// Specifies the name of the parameter group family to which the engine default parameters apply.
        public let parameterGroupFamily: String?

        @inlinable
        public init(engine: String? = nil, enginePatchVersion: String? = nil, engineVersion: String? = nil, parameterGroupFamily: String? = nil) {
            self.engine = engine
            self.enginePatchVersion = enginePatchVersion
            self.engineVersion = engineVersion
            self.parameterGroupFamily = parameterGroupFamily
        }

        private enum CodingKeys: String, CodingKey {
            case engine = "Engine"
            case enginePatchVersion = "EnginePatchVersion"
            case engineVersion = "EngineVersion"
            case parameterGroupFamily = "ParameterGroupFamily"
        }
    }

    public struct Event: AWSDecodableShape {
        /// The date and time when the event occurred.
        public let date: Date?
        /// The text of the event.
        public let message: String?
        /// The name for the source of the event. For example, if the event occurred at the cluster level, the identifier would be the name of the cluster.
        public let sourceName: String?
        /// Specifies the origin of this event - a cluster, a parameter group, a security group, etc.
        public let sourceType: SourceType?

        @inlinable
        public init(date: Date? = nil, message: String? = nil, sourceName: String? = nil, sourceType: SourceType? = nil) {
            self.date = date
            self.message = message
            self.sourceName = sourceName
            self.sourceType = sourceType
        }

        private enum CodingKeys: String, CodingKey {
            case date = "Date"
            case message = "Message"
            case sourceName = "SourceName"
            case sourceType = "SourceType"
        }
    }

    public struct FailoverShardRequest: AWSEncodableShape {
        /// The cluster being failed over.
        public let clusterName: String
        /// The name of the shard.
        public let shardName: String

        @inlinable
        public init(clusterName: String, shardName: String) {
            self.clusterName = clusterName
            self.shardName = shardName
        }

        private enum CodingKeys: String, CodingKey {
            case clusterName = "ClusterName"
            case shardName = "ShardName"
        }
    }

    public struct FailoverShardResponse: AWSDecodableShape {
        /// The cluster being failed over.
        public let cluster: Cluster?

        @inlinable
        public init(cluster: Cluster? = nil) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "Cluster"
        }
    }

    public struct Filter: AWSEncodableShape {
        /// The property being filtered. For example, UserName.
        public let name: String
        /// The property values to filter on. For example, "user-123".
        public let values: [String]

        @inlinable
        public init(name: String, values: [String]) {
            self.name = name
            self.values = values
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, pattern: "\\S")
            try self.values.forEach {
                try validate($0, name: "values[]", parent: name, pattern: "\\S")
            }
            try self.validate(self.values, name: "values", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
            case values = "Values"
        }
    }

    public struct ListAllowedMultiRegionClusterUpdatesRequest: AWSEncodableShape {
        /// The name of the multi-Region cluster.
        public let multiRegionClusterName: String

        @inlinable
        public init(multiRegionClusterName: String) {
            self.multiRegionClusterName = multiRegionClusterName
        }

        private enum CodingKeys: String, CodingKey {
            case multiRegionClusterName = "MultiRegionClusterName"
        }
    }

    public struct ListAllowedMultiRegionClusterUpdatesResponse: AWSDecodableShape {
        /// The node types that the cluster can be scaled down to.
        public let scaleDownNodeTypes: [String]?
        /// The node types that the cluster can be scaled up to.
        public let scaleUpNodeTypes: [String]?

        @inlinable
        public init(scaleDownNodeTypes: [String]? = nil, scaleUpNodeTypes: [String]? = nil) {
            self.scaleDownNodeTypes = scaleDownNodeTypes
            self.scaleUpNodeTypes = scaleUpNodeTypes
        }

        private enum CodingKeys: String, CodingKey {
            case scaleDownNodeTypes = "ScaleDownNodeTypes"
            case scaleUpNodeTypes = "ScaleUpNodeTypes"
        }
    }

    public struct ListAllowedNodeTypeUpdatesRequest: AWSEncodableShape {
        /// The name of the cluster you want to scale. MemoryDB uses the cluster name to identify the current node type being used by this cluster, and from that to create a list of node types you can scale up to.
        public let clusterName: String

        @inlinable
        public init(clusterName: String) {
            self.clusterName = clusterName
        }

        private enum CodingKeys: String, CodingKey {
            case clusterName = "ClusterName"
        }
    }

    public struct ListAllowedNodeTypeUpdatesResponse: AWSDecodableShape {
        /// A list node types which you can use to scale down your cluster.
        public let scaleDownNodeTypes: [String]?
        /// A list node types which you can use to scale up your cluster.
        public let scaleUpNodeTypes: [String]?

        @inlinable
        public init(scaleDownNodeTypes: [String]? = nil, scaleUpNodeTypes: [String]? = nil) {
            self.scaleDownNodeTypes = scaleDownNodeTypes
            self.scaleUpNodeTypes = scaleUpNodeTypes
        }

        private enum CodingKeys: String, CodingKey {
            case scaleDownNodeTypes = "ScaleDownNodeTypes"
            case scaleUpNodeTypes = "ScaleUpNodeTypes"
        }
    }

    public struct ListTagsRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the resource for which you want the list of tags.
        public let resourceArn: String

        @inlinable
        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
        }
    }

    public struct ListTagsResponse: AWSDecodableShape {
        /// A list of tags as key-value pairs.
        public let tagList: [Tag]?

        @inlinable
        public init(tagList: [Tag]? = nil) {
            self.tagList = tagList
        }

        private enum CodingKeys: String, CodingKey {
            case tagList = "TagList"
        }
    }

    public struct MultiRegionCluster: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the multi-Region cluster.
        public let arn: String?
        /// The clusters in this multi-Region cluster.
        public let clusters: [RegionalCluster]?
        /// The description of the multi-Region cluster.
        public let description: String?
        /// The name of the engine used by the multi-Region cluster.
        public let engine: String?
        /// The version of the engine used by the multi-Region cluster.
        public let engineVersion: String?
        /// The name of the multi-Region cluster.
        public let multiRegionClusterName: String?
        /// The name of the multi-Region parameter group associated with the cluster.
        public let multiRegionParameterGroupName: String?
        /// The node type used by the multi-Region cluster.
        public let nodeType: String?
        /// The number of shards in the multi-Region cluster.
        public let numberOfShards: Int?
        /// The current status of the multi-Region cluster.
        public let status: String?
        /// Indiciates if the multi-Region cluster is TLS enabled.
        public let tlsEnabled: Bool?

        @inlinable
        public init(arn: String? = nil, clusters: [RegionalCluster]? = nil, description: String? = nil, engine: String? = nil, engineVersion: String? = nil, multiRegionClusterName: String? = nil, multiRegionParameterGroupName: String? = nil, nodeType: String? = nil, numberOfShards: Int? = nil, status: String? = nil, tlsEnabled: Bool? = nil) {
            self.arn = arn
            self.clusters = clusters
            self.description = description
            self.engine = engine
            self.engineVersion = engineVersion
            self.multiRegionClusterName = multiRegionClusterName
            self.multiRegionParameterGroupName = multiRegionParameterGroupName
            self.nodeType = nodeType
            self.numberOfShards = numberOfShards
            self.status = status
            self.tlsEnabled = tlsEnabled
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "ARN"
            case clusters = "Clusters"
            case description = "Description"
            case engine = "Engine"
            case engineVersion = "EngineVersion"
            case multiRegionClusterName = "MultiRegionClusterName"
            case multiRegionParameterGroupName = "MultiRegionParameterGroupName"
            case nodeType = "NodeType"
            case numberOfShards = "NumberOfShards"
            case status = "Status"
            case tlsEnabled = "TLSEnabled"
        }
    }

    public struct Node: AWSDecodableShape {
        /// The Availability Zone in which the node resides
        public let availabilityZone: String?
        /// The date and time when the node was created.
        public let createTime: Date?
        /// The hostname for connecting to this node.
        public let endpoint: Endpoint?
        /// The  node identifier. A node name is a numeric identifier (0001, 0002, etc.). The combination of cluster name, shard name and node name uniquely identifies every node used in a customer's Amazon account.
        public let name: String?
        /// The status of the service update on the node
        public let status: String?

        @inlinable
        public init(availabilityZone: String? = nil, createTime: Date? = nil, endpoint: Endpoint? = nil, name: String? = nil, status: String? = nil) {
            self.availabilityZone = availabilityZone
            self.createTime = createTime
            self.endpoint = endpoint
            self.name = name
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZone = "AvailabilityZone"
            case createTime = "CreateTime"
            case endpoint = "Endpoint"
            case name = "Name"
            case status = "Status"
        }
    }

    public struct Parameter: AWSDecodableShape {
        /// The valid range of values for the parameter.
        public let allowedValues: String?
        /// The parameter's data type
        public let dataType: String?
        /// A description of the parameter
        public let description: String?
        /// The earliest engine version to which the parameter can apply.
        public let minimumEngineVersion: String?
        /// The name of the parameter
        public let name: String?
        /// The value of the parameter
        public let value: String?

        @inlinable
        public init(allowedValues: String? = nil, dataType: String? = nil, description: String? = nil, minimumEngineVersion: String? = nil, name: String? = nil, value: String? = nil) {
            self.allowedValues = allowedValues
            self.dataType = dataType
            self.description = description
            self.minimumEngineVersion = minimumEngineVersion
            self.name = name
            self.value = value
        }

        private enum CodingKeys: String, CodingKey {
            case allowedValues = "AllowedValues"
            case dataType = "DataType"
            case description = "Description"
            case minimumEngineVersion = "MinimumEngineVersion"
            case name = "Name"
            case value = "Value"
        }
    }

    public struct ParameterGroup: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the parameter group
        public let arn: String?
        /// A description of the parameter group
        public let description: String?
        /// The name of the parameter group family that this  parameter group is compatible with.
        public let family: String?
        /// The name of the parameter group
        public let name: String?

        @inlinable
        public init(arn: String? = nil, description: String? = nil, family: String? = nil, name: String? = nil) {
            self.arn = arn
            self.description = description
            self.family = family
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "ARN"
            case description = "Description"
            case family = "Family"
            case name = "Name"
        }
    }

    public struct ParameterNameValue: AWSEncodableShape {
        /// The name of the parameter
        public let parameterName: String?
        /// The value of the parameter
        public let parameterValue: String?

        @inlinable
        public init(parameterName: String? = nil, parameterValue: String? = nil) {
            self.parameterName = parameterName
            self.parameterValue = parameterValue
        }

        private enum CodingKeys: String, CodingKey {
            case parameterName = "ParameterName"
            case parameterValue = "ParameterValue"
        }
    }

    public struct PendingModifiedServiceUpdate: AWSDecodableShape {
        /// The unique ID of the service update
        public let serviceUpdateName: String?
        /// The status of the service update
        public let status: ServiceUpdateStatus?

        @inlinable
        public init(serviceUpdateName: String? = nil, status: ServiceUpdateStatus? = nil) {
            self.serviceUpdateName = serviceUpdateName
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case serviceUpdateName = "ServiceUpdateName"
            case status = "Status"
        }
    }

    public struct PurchaseReservedNodesOfferingRequest: AWSEncodableShape {
        /// The number of node instances to reserve.
        public let nodeCount: Int?
        /// A customer-specified identifier to track this reservation.
        public let reservationId: String?
        /// The ID of the reserved node offering to purchase.
        public let reservedNodesOfferingId: String
        /// A list of tags to be added to this resource. A tag is a key-value pair. A tag key must be accompanied by a tag value, although null is accepted.
        public let tags: [Tag]?

        @inlinable
        public init(nodeCount: Int? = nil, reservationId: String? = nil, reservedNodesOfferingId: String, tags: [Tag]? = nil) {
            self.nodeCount = nodeCount
            self.reservationId = reservationId
            self.reservedNodesOfferingId = reservedNodesOfferingId
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case nodeCount = "NodeCount"
            case reservationId = "ReservationId"
            case reservedNodesOfferingId = "ReservedNodesOfferingId"
            case tags = "Tags"
        }
    }

    public struct PurchaseReservedNodesOfferingResponse: AWSDecodableShape {
        /// Represents the output of a PurchaseReservedNodesOffering operation.
        public let reservedNode: ReservedNode?

        @inlinable
        public init(reservedNode: ReservedNode? = nil) {
            self.reservedNode = reservedNode
        }

        private enum CodingKeys: String, CodingKey {
            case reservedNode = "ReservedNode"
        }
    }

    public struct RecurringCharge: AWSDecodableShape {
        /// The amount of the recurring charge to run this reserved node.
        public let recurringChargeAmount: Double?
        /// The frequency of the recurring price charged to run this reserved node.
        public let recurringChargeFrequency: String?

        @inlinable
        public init(recurringChargeAmount: Double? = nil, recurringChargeFrequency: String? = nil) {
            self.recurringChargeAmount = recurringChargeAmount
            self.recurringChargeFrequency = recurringChargeFrequency
        }

        private enum CodingKeys: String, CodingKey {
            case recurringChargeAmount = "RecurringChargeAmount"
            case recurringChargeFrequency = "RecurringChargeFrequency"
        }
    }

    public struct RegionalCluster: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) the Regional cluster
        public let arn: String?
        /// The name of the Regional cluster
        public let clusterName: String?
        /// The Region the current Regional cluster is assigned to.
        public let region: String?
        /// The status of the Regional cluster.
        public let status: String?

        @inlinable
        public init(arn: String? = nil, clusterName: String? = nil, region: String? = nil, status: String? = nil) {
            self.arn = arn
            self.clusterName = clusterName
            self.region = region
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "ARN"
            case clusterName = "ClusterName"
            case region = "Region"
            case status = "Status"
        }
    }

    public struct ReplicaConfigurationRequest: AWSEncodableShape {
        /// The number of replicas to scale up or down to
        public let replicaCount: Int?

        @inlinable
        public init(replicaCount: Int? = nil) {
            self.replicaCount = replicaCount
        }

        private enum CodingKeys: String, CodingKey {
            case replicaCount = "ReplicaCount"
        }
    }

    public struct ReservedNode: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the reserved node.
        public let arn: String?
        /// The duration of the reservation in seconds.
        public let duration: Int?
        /// The fixed price charged for this reserved node.
        public let fixedPrice: Double?
        /// The number of nodes that have been reserved.
        public let nodeCount: Int?
        /// The node type for the reserved nodes.
        public let nodeType: String?
        /// The offering type of this reserved node.
        public let offeringType: String?
        /// The recurring price charged to run this reserved node.
        public let recurringCharges: [RecurringCharge]?
        /// A customer-specified identifier to track this reservation.
        public let reservationId: String?
        /// The ID of the reserved node offering to purchase.
        public let reservedNodesOfferingId: String?
        /// The time the reservation started.
        public let startTime: Date?
        /// The state of the reserved node.
        public let state: String?

        @inlinable
        public init(arn: String? = nil, duration: Int? = nil, fixedPrice: Double? = nil, nodeCount: Int? = nil, nodeType: String? = nil, offeringType: String? = nil, recurringCharges: [RecurringCharge]? = nil, reservationId: String? = nil, reservedNodesOfferingId: String? = nil, startTime: Date? = nil, state: String? = nil) {
            self.arn = arn
            self.duration = duration
            self.fixedPrice = fixedPrice
            self.nodeCount = nodeCount
            self.nodeType = nodeType
            self.offeringType = offeringType
            self.recurringCharges = recurringCharges
            self.reservationId = reservationId
            self.reservedNodesOfferingId = reservedNodesOfferingId
            self.startTime = startTime
            self.state = state
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "ARN"
            case duration = "Duration"
            case fixedPrice = "FixedPrice"
            case nodeCount = "NodeCount"
            case nodeType = "NodeType"
            case offeringType = "OfferingType"
            case recurringCharges = "RecurringCharges"
            case reservationId = "ReservationId"
            case reservedNodesOfferingId = "ReservedNodesOfferingId"
            case startTime = "StartTime"
            case state = "State"
        }
    }

    public struct ReservedNodesOffering: AWSDecodableShape {
        /// The duration of the reservation in seconds.
        public let duration: Int?
        /// The fixed price charged for this reserved node.
        public let fixedPrice: Double?
        /// The node type for the reserved nodes. For more information, see Supported node types.
        public let nodeType: String?
        /// The offering type of this reserved node.
        public let offeringType: String?
        /// The recurring price charged to run this reserved node.
        public let recurringCharges: [RecurringCharge]?
        /// The offering identifier.
        public let reservedNodesOfferingId: String?

        @inlinable
        public init(duration: Int? = nil, fixedPrice: Double? = nil, nodeType: String? = nil, offeringType: String? = nil, recurringCharges: [RecurringCharge]? = nil, reservedNodesOfferingId: String? = nil) {
            self.duration = duration
            self.fixedPrice = fixedPrice
            self.nodeType = nodeType
            self.offeringType = offeringType
            self.recurringCharges = recurringCharges
            self.reservedNodesOfferingId = reservedNodesOfferingId
        }

        private enum CodingKeys: String, CodingKey {
            case duration = "Duration"
            case fixedPrice = "FixedPrice"
            case nodeType = "NodeType"
            case offeringType = "OfferingType"
            case recurringCharges = "RecurringCharges"
            case reservedNodesOfferingId = "ReservedNodesOfferingId"
        }
    }

    public struct ResetParameterGroupRequest: AWSEncodableShape {
        /// If true, all parameters in the parameter group are reset to their default values. If false, only the parameters listed by ParameterNames are reset to their default values.
        public let allParameters: Bool?
        /// The name of the parameter group to reset.
        public let parameterGroupName: String
        /// An array of parameter names to reset to their default values. If AllParameters is true, do not use ParameterNames. If AllParameters is false, you must specify the name of at least one parameter to reset.
        public let parameterNames: [String]?

        @inlinable
        public init(allParameters: Bool? = nil, parameterGroupName: String, parameterNames: [String]? = nil) {
            self.allParameters = allParameters
            self.parameterGroupName = parameterGroupName
            self.parameterNames = parameterNames
        }

        private enum CodingKeys: String, CodingKey {
            case allParameters = "AllParameters"
            case parameterGroupName = "ParameterGroupName"
            case parameterNames = "ParameterNames"
        }
    }

    public struct ResetParameterGroupResponse: AWSDecodableShape {
        /// The parameter group being reset.
        public let parameterGroup: ParameterGroup?

        @inlinable
        public init(parameterGroup: ParameterGroup? = nil) {
            self.parameterGroup = parameterGroup
        }

        private enum CodingKeys: String, CodingKey {
            case parameterGroup = "ParameterGroup"
        }
    }

    public struct ReshardingStatus: AWSDecodableShape {
        /// The status of the online resharding slot migration
        public let slotMigration: SlotMigration?

        @inlinable
        public init(slotMigration: SlotMigration? = nil) {
            self.slotMigration = slotMigration
        }

        private enum CodingKeys: String, CodingKey {
            case slotMigration = "SlotMigration"
        }
    }

    public struct SecurityGroupMembership: AWSDecodableShape {
        /// The identifier of the security group.
        public let securityGroupId: String?
        /// The status of the security group membership. The status changes whenever a security group is modified, or when the security groups assigned to a cluster are modified.
        public let status: String?

        @inlinable
        public init(securityGroupId: String? = nil, status: String? = nil) {
            self.securityGroupId = securityGroupId
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case securityGroupId = "SecurityGroupId"
            case status = "Status"
        }
    }

    public struct ServiceUpdate: AWSDecodableShape {
        /// The date at which the service update will be automatically applied
        public let autoUpdateStartDate: Date?
        /// The name of the cluster to which the service update applies
        public let clusterName: String?
        /// Provides details of the service update
        public let description: String?
        /// The name of the engine for which a service update is available.
        public let engine: String?
        /// A list of nodes updated by the service update
        public let nodesUpdated: String?
        /// The date when the service update is initially available
        public let releaseDate: Date?
        /// The unique ID of the service update
        public let serviceUpdateName: String?
        /// The status of the service update
        public let status: ServiceUpdateStatus?
        /// Reflects the nature of the service update
        public let type: ServiceUpdateType?

        @inlinable
        public init(autoUpdateStartDate: Date? = nil, clusterName: String? = nil, description: String? = nil, engine: String? = nil, nodesUpdated: String? = nil, releaseDate: Date? = nil, serviceUpdateName: String? = nil, status: ServiceUpdateStatus? = nil, type: ServiceUpdateType? = nil) {
            self.autoUpdateStartDate = autoUpdateStartDate
            self.clusterName = clusterName
            self.description = description
            self.engine = engine
            self.nodesUpdated = nodesUpdated
            self.releaseDate = releaseDate
            self.serviceUpdateName = serviceUpdateName
            self.status = status
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case autoUpdateStartDate = "AutoUpdateStartDate"
            case clusterName = "ClusterName"
            case description = "Description"
            case engine = "Engine"
            case nodesUpdated = "NodesUpdated"
            case releaseDate = "ReleaseDate"
            case serviceUpdateName = "ServiceUpdateName"
            case status = "Status"
            case type = "Type"
        }
    }

    public struct ServiceUpdateRequest: AWSEncodableShape {
        /// The unique ID of the service update
        public let serviceUpdateNameToApply: String?

        @inlinable
        public init(serviceUpdateNameToApply: String? = nil) {
            self.serviceUpdateNameToApply = serviceUpdateNameToApply
        }

        private enum CodingKeys: String, CodingKey {
            case serviceUpdateNameToApply = "ServiceUpdateNameToApply"
        }
    }

    public struct Shard: AWSDecodableShape {
        /// The name of the shard
        public let name: String?
        /// A list containing information about individual nodes within the shard
        public let nodes: [Node]?
        /// The number of nodes in the shard
        public let numberOfNodes: Int?
        /// The keyspace for this shard.
        public let slots: String?
        /// The current state of this replication group - creating, available, modifying, deleting.
        public let status: String?

        @inlinable
        public init(name: String? = nil, nodes: [Node]? = nil, numberOfNodes: Int? = nil, slots: String? = nil, status: String? = nil) {
            self.name = name
            self.nodes = nodes
            self.numberOfNodes = numberOfNodes
            self.slots = slots
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case name = "Name"
            case nodes = "Nodes"
            case numberOfNodes = "NumberOfNodes"
            case slots = "Slots"
            case status = "Status"
        }
    }

    public struct ShardConfiguration: AWSDecodableShape {
        /// The number of read replica nodes in this shard.
        public let replicaCount: Int?
        /// A string that specifies the keyspace for a particular node group. Keyspaces range from 0 to 16,383. The string is in the format startkey-endkey.
        public let slots: String?

        @inlinable
        public init(replicaCount: Int? = nil, slots: String? = nil) {
            self.replicaCount = replicaCount
            self.slots = slots
        }

        private enum CodingKeys: String, CodingKey {
            case replicaCount = "ReplicaCount"
            case slots = "Slots"
        }
    }

    public struct ShardConfigurationRequest: AWSEncodableShape {
        /// The number of shards in the cluster
        public let shardCount: Int?

        @inlinable
        public init(shardCount: Int? = nil) {
            self.shardCount = shardCount
        }

        private enum CodingKeys: String, CodingKey {
            case shardCount = "ShardCount"
        }
    }

    public struct ShardDetail: AWSDecodableShape {
        /// The configuration details of the shard
        public let configuration: ShardConfiguration?
        /// The name of the shard
        public let name: String?
        /// The size of the shard's snapshot
        public let size: String?
        /// The date and time that the shard's snapshot was created
        public let snapshotCreationTime: Date?

        @inlinable
        public init(configuration: ShardConfiguration? = nil, name: String? = nil, size: String? = nil, snapshotCreationTime: Date? = nil) {
            self.configuration = configuration
            self.name = name
            self.size = size
            self.snapshotCreationTime = snapshotCreationTime
        }

        private enum CodingKeys: String, CodingKey {
            case configuration = "Configuration"
            case name = "Name"
            case size = "Size"
            case snapshotCreationTime = "SnapshotCreationTime"
        }
    }

    public struct SlotMigration: AWSDecodableShape {
        /// The percentage of the slot migration that is complete.
        public let progressPercentage: Double?

        @inlinable
        public init(progressPercentage: Double? = nil) {
            self.progressPercentage = progressPercentage
        }

        private enum CodingKeys: String, CodingKey {
            case progressPercentage = "ProgressPercentage"
        }
    }

    public struct Snapshot: AWSDecodableShape {
        /// The ARN (Amazon Resource Name) of the snapshot.
        public let arn: String?
        /// The configuration of the cluster from which the snapshot was taken
        public let clusterConfiguration: ClusterConfiguration?
        /// Enables data tiering. Data tiering is only supported for clusters using the r6gd node type.  This parameter must be set when using r6gd nodes. For more information, see Data tiering.
        public let dataTiering: DataTieringStatus?
        /// The ID of the KMS key used to encrypt the snapshot.
        public let kmsKeyId: String?
        /// The name of the snapshot
        public let name: String?
        /// Indicates whether the snapshot is from an automatic backup (automated) or was created manually (manual).
        public let source: String?
        /// The status of the snapshot. Valid values: creating | available | restoring | copying | deleting.
        public let status: String?

        @inlinable
        public init(arn: String? = nil, clusterConfiguration: ClusterConfiguration? = nil, dataTiering: DataTieringStatus? = nil, kmsKeyId: String? = nil, name: String? = nil, source: String? = nil, status: String? = nil) {
            self.arn = arn
            self.clusterConfiguration = clusterConfiguration
            self.dataTiering = dataTiering
            self.kmsKeyId = kmsKeyId
            self.name = name
            self.source = source
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "ARN"
            case clusterConfiguration = "ClusterConfiguration"
            case dataTiering = "DataTiering"
            case kmsKeyId = "KmsKeyId"
            case name = "Name"
            case source = "Source"
            case status = "Status"
        }
    }

    public struct Subnet: AWSDecodableShape {
        /// The Availability Zone where the subnet resides
        public let availabilityZone: AvailabilityZone?
        /// The unique identifier for the subnet.
        public let identifier: String?
        /// The network types supported by this subnet. Returns an array of strings that can include 'ipv4', 'ipv6', or both, indicating whether the subnet supports IPv4 only, IPv6 only, or dual-stack deployments.
        public let supportedNetworkTypes: [NetworkType]?

        @inlinable
        public init(availabilityZone: AvailabilityZone? = nil, identifier: String? = nil, supportedNetworkTypes: [NetworkType]? = nil) {
            self.availabilityZone = availabilityZone
            self.identifier = identifier
            self.supportedNetworkTypes = supportedNetworkTypes
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZone = "AvailabilityZone"
            case identifier = "Identifier"
            case supportedNetworkTypes = "SupportedNetworkTypes"
        }
    }

    public struct SubnetGroup: AWSDecodableShape {
        /// The ARN (Amazon Resource Name) of the subnet group.
        public let arn: String?
        /// A description of the subnet group
        public let description: String?
        /// The name of the subnet group
        public let name: String?
        /// A list of subnets associated with the subnet group.
        public let subnets: [Subnet]?
        /// The network types supported by this subnet group. Returns an array of strings that can include 'ipv4', 'ipv6', or both, indicating the IP address types that can be used for clusters deployed in this subnet group.
        public let supportedNetworkTypes: [NetworkType]?
        /// The Amazon Virtual Private Cloud identifier (VPC ID) of the subnet group.
        public let vpcId: String?

        @inlinable
        public init(arn: String? = nil, description: String? = nil, name: String? = nil, subnets: [Subnet]? = nil, supportedNetworkTypes: [NetworkType]? = nil, vpcId: String? = nil) {
            self.arn = arn
            self.description = description
            self.name = name
            self.subnets = subnets
            self.supportedNetworkTypes = supportedNetworkTypes
            self.vpcId = vpcId
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "ARN"
            case description = "Description"
            case name = "Name"
            case subnets = "Subnets"
            case supportedNetworkTypes = "SupportedNetworkTypes"
            case vpcId = "VpcId"
        }
    }

    public struct Tag: AWSEncodableShape & AWSDecodableShape {
        /// The key for the tag. May not be null.
        public let key: String?
        /// The tag's value. May be null.
        public let value: String?

        @inlinable
        public init(key: String? = nil, value: String? = nil) {
            self.key = key
            self.value = value
        }

        private enum CodingKeys: String, CodingKey {
            case key = "Key"
            case value = "Value"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the resource to which the tags are to be added.
        public let resourceArn: String
        /// A list of tags to be added to this resource. A tag is a key-value pair. A tag key must be accompanied by a tag value, although null is accepted.
        public let tags: [Tag]

        @inlinable
        public init(resourceArn: String, tags: [Tag]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
            case tags = "Tags"
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        /// A list of tags as key-value pairs.
        public let tagList: [Tag]?

        @inlinable
        public init(tagList: [Tag]? = nil) {
            self.tagList = tagList
        }

        private enum CodingKeys: String, CodingKey {
            case tagList = "TagList"
        }
    }

    public struct UnprocessedCluster: AWSDecodableShape {
        /// The name of the cluster
        public let clusterName: String?
        /// The error message associated with the update failure
        public let errorMessage: String?
        /// The error type associated with the update failure
        public let errorType: String?

        @inlinable
        public init(clusterName: String? = nil, errorMessage: String? = nil, errorType: String? = nil) {
            self.clusterName = clusterName
            self.errorMessage = errorMessage
            self.errorType = errorType
        }

        private enum CodingKeys: String, CodingKey {
            case clusterName = "ClusterName"
            case errorMessage = "ErrorMessage"
            case errorType = "ErrorType"
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the resource to which the tags are to be removed.
        public let resourceArn: String
        /// The list of keys of the tags that are to be removed.
        public let tagKeys: [String]

        @inlinable
        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
            case tagKeys = "TagKeys"
        }
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        /// The list of tags removed.
        public let tagList: [Tag]?

        @inlinable
        public init(tagList: [Tag]? = nil) {
            self.tagList = tagList
        }

        private enum CodingKeys: String, CodingKey {
            case tagList = "TagList"
        }
    }

    public struct UpdateACLRequest: AWSEncodableShape {
        /// The name of the Access Control List.
        public let aclName: String
        /// The list of users to add to the Access Control List.
        public let userNamesToAdd: [String]?
        /// The list of users to remove from the Access Control List.
        public let userNamesToRemove: [String]?

        @inlinable
        public init(aclName: String, userNamesToAdd: [String]? = nil, userNamesToRemove: [String]? = nil) {
            self.aclName = aclName
            self.userNamesToAdd = userNamesToAdd
            self.userNamesToRemove = userNamesToRemove
        }

        public func validate(name: String) throws {
            try self.userNamesToAdd?.forEach {
                try validate($0, name: "userNamesToAdd[]", parent: name, min: 1)
                try validate($0, name: "userNamesToAdd[]", parent: name, pattern: "^[a-zA-Z][a-zA-Z0-9\\-]*$")
            }
            try self.validate(self.userNamesToAdd, name: "userNamesToAdd", parent: name, min: 1)
            try self.userNamesToRemove?.forEach {
                try validate($0, name: "userNamesToRemove[]", parent: name, min: 1)
                try validate($0, name: "userNamesToRemove[]", parent: name, pattern: "^[a-zA-Z][a-zA-Z0-9\\-]*$")
            }
            try self.validate(self.userNamesToRemove, name: "userNamesToRemove", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case aclName = "ACLName"
            case userNamesToAdd = "UserNamesToAdd"
            case userNamesToRemove = "UserNamesToRemove"
        }
    }

    public struct UpdateACLResponse: AWSDecodableShape {
        /// The updated Access Control List.
        public let acl: ACL?

        @inlinable
        public init(acl: ACL? = nil) {
            self.acl = acl
        }

        private enum CodingKeys: String, CodingKey {
            case acl = "ACL"
        }
    }

    public struct UpdateClusterRequest: AWSEncodableShape {
        /// The Access Control List that is associated with the cluster.
        public let aclName: String?
        /// The name of the cluster to update.
        public let clusterName: String
        /// The description of the cluster to update.
        public let description: String?
        /// The name of the engine to be used for the cluster.
        public let engine: String?
        /// The upgraded version of the engine to be run on the nodes. You can upgrade to a newer engine version, but you cannot downgrade to an earlier engine version. If you want to use an earlier engine version, you must delete the existing cluster and create it anew with the earlier engine version.
        public let engineVersion: String?
        /// The mechanism for discovering IP addresses for the cluster discovery protocol. Valid values are 'ipv4' or 'ipv6'. When set to 'ipv4', cluster discovery functions such as cluster slots, cluster shards, and cluster nodes will return IPv4 addresses for cluster nodes. When set to 'ipv6', the cluster discovery functions return IPv6 addresses for cluster nodes. The value must be compatible with the NetworkType parameter. If not specified, the default is 'ipv4'.
        public let ipDiscovery: IpDiscovery?
        /// Specifies the weekly time range during which maintenance on the cluster is performed. It is specified as a range in the format ddd:hh24:mi-ddd:hh24:mi (24H Clock UTC). The minimum maintenance window is a 60 minute period. Valid values for ddd are:    sun     mon     tue     wed     thu     fri     sat    Example: sun:23:00-mon:01:30
        public let maintenanceWindow: String?
        /// A valid node type that you want to scale this cluster up or down to.
        public let nodeType: String?
        /// The name of the parameter group to update.
        public let parameterGroupName: String?
        /// The number of replicas that will reside in each shard.
        public let replicaConfiguration: ReplicaConfigurationRequest?
        /// The SecurityGroupIds to update.
        public let securityGroupIds: [String]?
        /// The number of shards in the cluster.
        public let shardConfiguration: ShardConfigurationRequest?
        /// The number of days for which MemoryDB retains automatic cluster snapshots before deleting them. For example, if you set SnapshotRetentionLimit to 5, a snapshot that was taken today is retained for 5 days before being deleted.
        public let snapshotRetentionLimit: Int?
        /// The daily time range (in UTC) during which MemoryDB begins taking a daily snapshot of your cluster.
        public let snapshotWindow: String?
        /// The SNS topic ARN to update.
        public let snsTopicArn: String?
        /// The status of the Amazon SNS notification topic. Notifications are sent only if the status is active.
        public let snsTopicStatus: String?

        @inlinable
        public init(aclName: String? = nil, clusterName: String, description: String? = nil, engine: String? = nil, engineVersion: String? = nil, ipDiscovery: IpDiscovery? = nil, maintenanceWindow: String? = nil, nodeType: String? = nil, parameterGroupName: String? = nil, replicaConfiguration: ReplicaConfigurationRequest? = nil, securityGroupIds: [String]? = nil, shardConfiguration: ShardConfigurationRequest? = nil, snapshotRetentionLimit: Int? = nil, snapshotWindow: String? = nil, snsTopicArn: String? = nil, snsTopicStatus: String? = nil) {
            self.aclName = aclName
            self.clusterName = clusterName
            self.description = description
            self.engine = engine
            self.engineVersion = engineVersion
            self.ipDiscovery = ipDiscovery
            self.maintenanceWindow = maintenanceWindow
            self.nodeType = nodeType
            self.parameterGroupName = parameterGroupName
            self.replicaConfiguration = replicaConfiguration
            self.securityGroupIds = securityGroupIds
            self.shardConfiguration = shardConfiguration
            self.snapshotRetentionLimit = snapshotRetentionLimit
            self.snapshotWindow = snapshotWindow
            self.snsTopicArn = snsTopicArn
            self.snsTopicStatus = snsTopicStatus
        }

        public func validate(name: String) throws {
            try self.validate(self.aclName, name: "aclName", parent: name, min: 1)
            try self.validate(self.aclName, name: "aclName", parent: name, pattern: "^[a-zA-Z][a-zA-Z0-9\\-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case aclName = "ACLName"
            case clusterName = "ClusterName"
            case description = "Description"
            case engine = "Engine"
            case engineVersion = "EngineVersion"
            case ipDiscovery = "IpDiscovery"
            case maintenanceWindow = "MaintenanceWindow"
            case nodeType = "NodeType"
            case parameterGroupName = "ParameterGroupName"
            case replicaConfiguration = "ReplicaConfiguration"
            case securityGroupIds = "SecurityGroupIds"
            case shardConfiguration = "ShardConfiguration"
            case snapshotRetentionLimit = "SnapshotRetentionLimit"
            case snapshotWindow = "SnapshotWindow"
            case snsTopicArn = "SnsTopicArn"
            case snsTopicStatus = "SnsTopicStatus"
        }
    }

    public struct UpdateClusterResponse: AWSDecodableShape {
        /// The updated cluster.
        public let cluster: Cluster?

        @inlinable
        public init(cluster: Cluster? = nil) {
            self.cluster = cluster
        }

        private enum CodingKeys: String, CodingKey {
            case cluster = "Cluster"
        }
    }

    public struct UpdateMultiRegionClusterRequest: AWSEncodableShape {
        /// A new description for the multi-Region cluster.
        public let description: String?
        /// The new engine version to be used for the multi-Region cluster.
        public let engineVersion: String?
        /// The name of the multi-Region cluster to be updated.
        public let multiRegionClusterName: String
        /// The new multi-Region parameter group to be associated with the cluster.
        public let multiRegionParameterGroupName: String?
        /// The new node type to be used for the multi-Region cluster.
        public let nodeType: String?
        public let shardConfiguration: ShardConfigurationRequest?
        /// The strategy to use for the update operation. Supported values are "coordinated" or "uncoordinated".
        public let updateStrategy: UpdateStrategy?

        @inlinable
        public init(description: String? = nil, engineVersion: String? = nil, multiRegionClusterName: String, multiRegionParameterGroupName: String? = nil, nodeType: String? = nil, shardConfiguration: ShardConfigurationRequest? = nil, updateStrategy: UpdateStrategy? = nil) {
            self.description = description
            self.engineVersion = engineVersion
            self.multiRegionClusterName = multiRegionClusterName
            self.multiRegionParameterGroupName = multiRegionParameterGroupName
            self.nodeType = nodeType
            self.shardConfiguration = shardConfiguration
            self.updateStrategy = updateStrategy
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case engineVersion = "EngineVersion"
            case multiRegionClusterName = "MultiRegionClusterName"
            case multiRegionParameterGroupName = "MultiRegionParameterGroupName"
            case nodeType = "NodeType"
            case shardConfiguration = "ShardConfiguration"
            case updateStrategy = "UpdateStrategy"
        }
    }

    public struct UpdateMultiRegionClusterResponse: AWSDecodableShape {
        /// The status of updating the multi-Region cluster.
        public let multiRegionCluster: MultiRegionCluster?

        @inlinable
        public init(multiRegionCluster: MultiRegionCluster? = nil) {
            self.multiRegionCluster = multiRegionCluster
        }

        private enum CodingKeys: String, CodingKey {
            case multiRegionCluster = "MultiRegionCluster"
        }
    }

    public struct UpdateParameterGroupRequest: AWSEncodableShape {
        /// The name of the parameter group to update.
        public let parameterGroupName: String
        /// An array of parameter names and values for the parameter update. You must supply at least one parameter name and value; subsequent arguments are optional. A maximum of 20 parameters may be updated per request.
        public let parameterNameValues: [ParameterNameValue]

        @inlinable
        public init(parameterGroupName: String, parameterNameValues: [ParameterNameValue]) {
            self.parameterGroupName = parameterGroupName
            self.parameterNameValues = parameterNameValues
        }

        private enum CodingKeys: String, CodingKey {
            case parameterGroupName = "ParameterGroupName"
            case parameterNameValues = "ParameterNameValues"
        }
    }

    public struct UpdateParameterGroupResponse: AWSDecodableShape {
        /// The updated parameter group
        public let parameterGroup: ParameterGroup?

        @inlinable
        public init(parameterGroup: ParameterGroup? = nil) {
            self.parameterGroup = parameterGroup
        }

        private enum CodingKeys: String, CodingKey {
            case parameterGroup = "ParameterGroup"
        }
    }

    public struct UpdateSubnetGroupRequest: AWSEncodableShape {
        /// A description of the subnet group
        public let description: String?
        /// The name of the subnet group
        public let subnetGroupName: String
        /// The EC2 subnet IDs for the subnet group.
        public let subnetIds: [String]?

        @inlinable
        public init(description: String? = nil, subnetGroupName: String, subnetIds: [String]? = nil) {
            self.description = description
            self.subnetGroupName = subnetGroupName
            self.subnetIds = subnetIds
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case subnetGroupName = "SubnetGroupName"
            case subnetIds = "SubnetIds"
        }
    }

    public struct UpdateSubnetGroupResponse: AWSDecodableShape {
        /// The updated subnet group
        public let subnetGroup: SubnetGroup?

        @inlinable
        public init(subnetGroup: SubnetGroup? = nil) {
            self.subnetGroup = subnetGroup
        }

        private enum CodingKeys: String, CodingKey {
            case subnetGroup = "SubnetGroup"
        }
    }

    public struct UpdateUserRequest: AWSEncodableShape {
        /// Access permissions string used for this user.
        public let accessString: String?
        /// Denotes the user's authentication properties, such as whether it requires a password to authenticate.
        public let authenticationMode: AuthenticationMode?
        /// The name of the user
        public let userName: String

        @inlinable
        public init(accessString: String? = nil, authenticationMode: AuthenticationMode? = nil, userName: String) {
            self.accessString = accessString
            self.authenticationMode = authenticationMode
            self.userName = userName
        }

        public func validate(name: String) throws {
            try self.validate(self.accessString, name: "accessString", parent: name, pattern: "\\S")
            try self.authenticationMode?.validate(name: "\(name).authenticationMode")
            try self.validate(self.userName, name: "userName", parent: name, min: 1)
            try self.validate(self.userName, name: "userName", parent: name, pattern: "^[a-zA-Z][a-zA-Z0-9\\-]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case accessString = "AccessString"
            case authenticationMode = "AuthenticationMode"
            case userName = "UserName"
        }
    }

    public struct UpdateUserResponse: AWSDecodableShape {
        /// The updated user
        public let user: User?

        @inlinable
        public init(user: User? = nil) {
            self.user = user
        }

        private enum CodingKeys: String, CodingKey {
            case user = "User"
        }
    }

    public struct User: AWSDecodableShape {
        /// Access permissions string used for this user.
        public let accessString: String?
        /// The names of the Access Control Lists to which the user belongs
        public let aclNames: [String]?
        /// The Amazon Resource Name (ARN) of the user.
        public let arn: String?
        /// Denotes whether the user requires a password to authenticate.
        public let authentication: Authentication?
        /// The minimum engine version supported for the user
        public let minimumEngineVersion: String?
        /// The name of the user
        public let name: String?
        /// Indicates the user status. Can be "active", "modifying" or "deleting".
        public let status: String?

        @inlinable
        public init(accessString: String? = nil, aclNames: [String]? = nil, arn: String? = nil, authentication: Authentication? = nil, minimumEngineVersion: String? = nil, name: String? = nil, status: String? = nil) {
            self.accessString = accessString
            self.aclNames = aclNames
            self.arn = arn
            self.authentication = authentication
            self.minimumEngineVersion = minimumEngineVersion
            self.name = name
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case accessString = "AccessString"
            case aclNames = "ACLNames"
            case arn = "ARN"
            case authentication = "Authentication"
            case minimumEngineVersion = "MinimumEngineVersion"
            case name = "Name"
            case status = "Status"
        }
    }
}

// MARK: - Errors

/// Error enum for MemoryDB
public struct MemoryDBErrorType: AWSErrorType {
    enum Code: String {
        case aclAlreadyExistsFault = "ACLAlreadyExistsFault"
        case aclNotFoundFault = "ACLNotFoundFault"
        case aclQuotaExceededFault = "ACLQuotaExceededFault"
        case apiCallRateForCustomerExceededFault = "APICallRateForCustomerExceededFault"
        case clusterAlreadyExistsFault = "ClusterAlreadyExistsFault"
        case clusterNotFoundFault = "ClusterNotFoundFault"
        case clusterQuotaForCustomerExceededFault = "ClusterQuotaForCustomerExceededFault"
        case defaultUserRequired = "DefaultUserRequired"
        case duplicateUserNameFault = "DuplicateUserNameFault"
        case insufficientClusterCapacityFault = "InsufficientClusterCapacityFault"
        case invalidACLStateFault = "InvalidACLStateFault"
        case invalidARNFault = "InvalidARNFault"
        case invalidClusterStateFault = "InvalidClusterStateFault"
        case invalidCredentialsException = "InvalidCredentialsException"
        case invalidKMSKeyFault = "InvalidKMSKeyFault"
        case invalidMultiRegionClusterStateFault = "InvalidMultiRegionClusterStateFault"
        case invalidNodeStateFault = "InvalidNodeStateFault"
        case invalidParameterCombinationException = "InvalidParameterCombinationException"
        case invalidParameterGroupStateFault = "InvalidParameterGroupStateFault"
        case invalidParameterValueException = "InvalidParameterValueException"
        case invalidSnapshotStateFault = "InvalidSnapshotStateFault"
        case invalidSubnet = "InvalidSubnet"
        case invalidUserStateFault = "InvalidUserStateFault"
        case invalidVPCNetworkStateFault = "InvalidVPCNetworkStateFault"
        case multiRegionClusterAlreadyExistsFault = "MultiRegionClusterAlreadyExistsFault"
        case multiRegionClusterNotFoundFault = "MultiRegionClusterNotFoundFault"
        case multiRegionParameterGroupNotFoundFault = "MultiRegionParameterGroupNotFoundFault"
        case noOperationFault = "NoOperationFault"
        case nodeQuotaForClusterExceededFault = "NodeQuotaForClusterExceededFault"
        case nodeQuotaForCustomerExceededFault = "NodeQuotaForCustomerExceededFault"
        case parameterGroupAlreadyExistsFault = "ParameterGroupAlreadyExistsFault"
        case parameterGroupNotFoundFault = "ParameterGroupNotFoundFault"
        case parameterGroupQuotaExceededFault = "ParameterGroupQuotaExceededFault"
        case reservedNodeAlreadyExistsFault = "ReservedNodeAlreadyExistsFault"
        case reservedNodeNotFoundFault = "ReservedNodeNotFoundFault"
        case reservedNodeQuotaExceededFault = "ReservedNodeQuotaExceededFault"
        case reservedNodesOfferingNotFoundFault = "ReservedNodesOfferingNotFoundFault"
        case serviceLinkedRoleNotFoundFault = "ServiceLinkedRoleNotFoundFault"
        case serviceUpdateNotFoundFault = "ServiceUpdateNotFoundFault"
        case shardNotFoundFault = "ShardNotFoundFault"
        case shardsPerClusterQuotaExceededFault = "ShardsPerClusterQuotaExceededFault"
        case snapshotAlreadyExistsFault = "SnapshotAlreadyExistsFault"
        case snapshotNotFoundFault = "SnapshotNotFoundFault"
        case snapshotQuotaExceededFault = "SnapshotQuotaExceededFault"
        case subnetGroupAlreadyExistsFault = "SubnetGroupAlreadyExistsFault"
        case subnetGroupInUseFault = "SubnetGroupInUseFault"
        case subnetGroupNotFoundFault = "SubnetGroupNotFoundFault"
        case subnetGroupQuotaExceededFault = "SubnetGroupQuotaExceededFault"
        case subnetInUse = "SubnetInUse"
        case subnetNotAllowedFault = "SubnetNotAllowedFault"
        case subnetQuotaExceededFault = "SubnetQuotaExceededFault"
        case tagNotFoundFault = "TagNotFoundFault"
        case tagQuotaPerResourceExceeded = "TagQuotaPerResourceExceeded"
        case testFailoverNotAvailableFault = "TestFailoverNotAvailableFault"
        case userAlreadyExistsFault = "UserAlreadyExistsFault"
        case userNotFoundFault = "UserNotFoundFault"
        case userQuotaExceededFault = "UserQuotaExceededFault"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize MemoryDB
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    public static var aclAlreadyExistsFault: Self { .init(.aclAlreadyExistsFault) }
    public static var aclNotFoundFault: Self { .init(.aclNotFoundFault) }
    public static var aclQuotaExceededFault: Self { .init(.aclQuotaExceededFault) }
    public static var apiCallRateForCustomerExceededFault: Self { .init(.apiCallRateForCustomerExceededFault) }
    public static var clusterAlreadyExistsFault: Self { .init(.clusterAlreadyExistsFault) }
    public static var clusterNotFoundFault: Self { .init(.clusterNotFoundFault) }
    public static var clusterQuotaForCustomerExceededFault: Self { .init(.clusterQuotaForCustomerExceededFault) }
    public static var defaultUserRequired: Self { .init(.defaultUserRequired) }
    public static var duplicateUserNameFault: Self { .init(.duplicateUserNameFault) }
    public static var insufficientClusterCapacityFault: Self { .init(.insufficientClusterCapacityFault) }
    public static var invalidACLStateFault: Self { .init(.invalidACLStateFault) }
    public static var invalidARNFault: Self { .init(.invalidARNFault) }
    public static var invalidClusterStateFault: Self { .init(.invalidClusterStateFault) }
    public static var invalidCredentialsException: Self { .init(.invalidCredentialsException) }
    public static var invalidKMSKeyFault: Self { .init(.invalidKMSKeyFault) }
    /// The requested operation cannot be performed on the multi-Region cluster in its current state.
    public static var invalidMultiRegionClusterStateFault: Self { .init(.invalidMultiRegionClusterStateFault) }
    public static var invalidNodeStateFault: Self { .init(.invalidNodeStateFault) }
    public static var invalidParameterCombinationException: Self { .init(.invalidParameterCombinationException) }
    public static var invalidParameterGroupStateFault: Self { .init(.invalidParameterGroupStateFault) }
    public static var invalidParameterValueException: Self { .init(.invalidParameterValueException) }
    public static var invalidSnapshotStateFault: Self { .init(.invalidSnapshotStateFault) }
    public static var invalidSubnet: Self { .init(.invalidSubnet) }
    public static var invalidUserStateFault: Self { .init(.invalidUserStateFault) }
    public static var invalidVPCNetworkStateFault: Self { .init(.invalidVPCNetworkStateFault) }
    /// A multi-Region cluster with the specified name already exists.
    public static var multiRegionClusterAlreadyExistsFault: Self { .init(.multiRegionClusterAlreadyExistsFault) }
    /// The specified multi-Region cluster does not exist.
    public static var multiRegionClusterNotFoundFault: Self { .init(.multiRegionClusterNotFoundFault) }
    /// The specified multi-Region parameter group does not exist.
    public static var multiRegionParameterGroupNotFoundFault: Self { .init(.multiRegionParameterGroupNotFoundFault) }
    public static var noOperationFault: Self { .init(.noOperationFault) }
    public static var nodeQuotaForClusterExceededFault: Self { .init(.nodeQuotaForClusterExceededFault) }
    public static var nodeQuotaForCustomerExceededFault: Self { .init(.nodeQuotaForCustomerExceededFault) }
    public static var parameterGroupAlreadyExistsFault: Self { .init(.parameterGroupAlreadyExistsFault) }
    public static var parameterGroupNotFoundFault: Self { .init(.parameterGroupNotFoundFault) }
    public static var parameterGroupQuotaExceededFault: Self { .init(.parameterGroupQuotaExceededFault) }
    /// You already have a reservation with the given identifier.
    public static var reservedNodeAlreadyExistsFault: Self { .init(.reservedNodeAlreadyExistsFault) }
    /// The requested node does not exist.
    public static var reservedNodeNotFoundFault: Self { .init(.reservedNodeNotFoundFault) }
    /// The request cannot be processed because it would exceed the user's node quota.
    public static var reservedNodeQuotaExceededFault: Self { .init(.reservedNodeQuotaExceededFault) }
    /// The requested node offering does not exist.
    public static var reservedNodesOfferingNotFoundFault: Self { .init(.reservedNodesOfferingNotFoundFault) }
    public static var serviceLinkedRoleNotFoundFault: Self { .init(.serviceLinkedRoleNotFoundFault) }
    public static var serviceUpdateNotFoundFault: Self { .init(.serviceUpdateNotFoundFault) }
    public static var shardNotFoundFault: Self { .init(.shardNotFoundFault) }
    public static var shardsPerClusterQuotaExceededFault: Self { .init(.shardsPerClusterQuotaExceededFault) }
    public static var snapshotAlreadyExistsFault: Self { .init(.snapshotAlreadyExistsFault) }
    public static var snapshotNotFoundFault: Self { .init(.snapshotNotFoundFault) }
    public static var snapshotQuotaExceededFault: Self { .init(.snapshotQuotaExceededFault) }
    public static var subnetGroupAlreadyExistsFault: Self { .init(.subnetGroupAlreadyExistsFault) }
    public static var subnetGroupInUseFault: Self { .init(.subnetGroupInUseFault) }
    public static var subnetGroupNotFoundFault: Self { .init(.subnetGroupNotFoundFault) }
    public static var subnetGroupQuotaExceededFault: Self { .init(.subnetGroupQuotaExceededFault) }
    public static var subnetInUse: Self { .init(.subnetInUse) }
    public static var subnetNotAllowedFault: Self { .init(.subnetNotAllowedFault) }
    public static var subnetQuotaExceededFault: Self { .init(.subnetQuotaExceededFault) }
    public static var tagNotFoundFault: Self { .init(.tagNotFoundFault) }
    public static var tagQuotaPerResourceExceeded: Self { .init(.tagQuotaPerResourceExceeded) }
    public static var testFailoverNotAvailableFault: Self { .init(.testFailoverNotAvailableFault) }
    public static var userAlreadyExistsFault: Self { .init(.userAlreadyExistsFault) }
    public static var userNotFoundFault: Self { .init(.userNotFoundFault) }
    public static var userQuotaExceededFault: Self { .init(.userQuotaExceededFault) }
}

extension MemoryDBErrorType: Equatable {
    public static func == (lhs: MemoryDBErrorType, rhs: MemoryDBErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension MemoryDBErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
